tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsHtml5TokenizerLoopPoliciesSIMD.h (26432B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef nsHtml5TokenizerLoopPoliciesSIMD_h
      6 #define nsHtml5TokenizerLoopPoliciesSIMD_h
      7 
      8 #include "mozilla/Attributes.h"
      9 #include "mozilla/htmlaccel/htmlaccelNotInline.h"
     10 
     11 /**
     12 * This policy does not report tokenizer transitions anywhere and does not
     13 * track line and column numbers. To be used for innerHTML.
     14 *
     15 * This the SIMD version for aarch64 and SSSE3-enabled x86/x86_64.
     16 */
     17 struct nsHtml5FastestPolicySIMD {
     18  static const bool reportErrors = false;
     19  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t transition(
     20      nsHtml5Highlighter* aHighlighter, int32_t aState, bool aReconsume,
     21      int32_t aPos) {
     22    return aState;
     23  }
     24  MOZ_ALWAYS_INLINE_EVEN_DEBUG static void completedNamedCharacterReference(
     25      nsHtml5Highlighter* aHighlighter) {}
     26 
     27  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementData(
     28      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
     29      int32_t endPos) {
     30    // We need to check bounds for the `buf[pos]` access below to be OK.
     31    // Instead of just checking that `pos` isn't equal to `endPos`, let's
     32    // check that have at least one SIMD stride of data in the same branch,
     33    // since if we don't have at least one SIMD stride of data, we don't
     34    // need to proceed.
     35    if (endPos - pos < 16) {
     36      return 0;
     37    }
     38    if (buf[pos] == '<') {
     39      // Quickly handle the case where there is one tag immediately
     40      // after another and the very first thing in the data state is a
     41      // less-than sign.
     42      return 0;
     43    }
     44    return mozilla::htmlaccel::AccelerateDataFastest(buf + pos, buf + endPos);
     45  }
     46 
     47  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementRawtext(
     48      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
     49      int32_t endPos) {
     50    // We need to check bounds for the `buf[pos]` access below to be OK.
     51    // Instead of just checking that `pos` isn't equal to `endPos`, let's
     52    // check that have at least one SIMD stride of data in the same branch,
     53    // since if we don't have at least one SIMD stride of data, we don't
     54    // need to proceed.
     55    if (endPos - pos < 16) {
     56      return 0;
     57    }
     58    if (buf[pos] == '<') {
     59      // Quickly handle the <iframe></iframe> case.
     60      return 0;
     61    }
     62    return mozilla::htmlaccel::AccelerateRawtextFastest(buf + pos,
     63                                                        buf + endPos);
     64  }
     65 
     66  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
     67  accelerateAdvancementScriptDataEscaped(nsHtml5Tokenizer* aTokenizer,
     68                                         char16_t* buf, int32_t pos,
     69                                         int32_t endPos) {
     70    // This state shares the SIMD part with the comment state, but this
     71    // wrapper needs to differ!
     72    return mozilla::htmlaccel::AccelerateCommentFastest(buf + pos,
     73                                                        buf + endPos);
     74  }
     75 
     76  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementComment(
     77      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
     78      int32_t endPos) {
     79    int32_t len = endPos - pos;
     80    int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
     81    if (len > strBufAvailable) {
     82      MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
     83      len = strBufAvailable;
     84    }
     85    int32_t advance = mozilla::htmlaccel::AccelerateCommentFastest(
     86        buf + pos, buf + pos + len);
     87    // States that on the non-SIMD path copy characters to strBuf also
     88    // need to do that in the SIMD case.
     89    nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
     90                                aTokenizer->strBufLen, advance);
     91    aTokenizer->strBufLen += advance;
     92    return advance;
     93  }
     94 
     95  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
     96  accelerateAdvancementAttributeValueSingleQuoted(nsHtml5Tokenizer* aTokenizer,
     97                                                  char16_t* buf, int32_t pos,
     98                                                  int32_t endPos) {
     99    int32_t len = endPos - pos;
    100    int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
    101    if (len > strBufAvailable) {
    102      MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
    103      len = strBufAvailable;
    104    }
    105    int32_t advance =
    106        mozilla::htmlaccel::AccelerateAttributeValueSingleQuotedFastest(
    107            buf + pos, buf + pos + len);
    108    // States that on the non-SIMD path copy characters to strBuf also
    109    // need to do that in the SIMD case.
    110    nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
    111                                aTokenizer->strBufLen, advance);
    112    aTokenizer->strBufLen += advance;
    113    return advance;
    114  }
    115 
    116  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
    117  accelerateAdvancementAttributeValueDoubleQuoted(nsHtml5Tokenizer* aTokenizer,
    118                                                  char16_t* buf, int32_t pos,
    119                                                  int32_t endPos) {
    120    int32_t len = endPos - pos;
    121    int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
    122    if (len > strBufAvailable) {
    123      MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
    124      len = strBufAvailable;
    125    }
    126    int32_t advance =
    127        mozilla::htmlaccel::AccelerateAttributeValueDoubleQuotedFastest(
    128            buf + pos, buf + pos + len);
    129    // States that on the non-SIMD path copy characters to strBuf also
    130    // need to do that in the SIMD case.
    131    nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
    132                                aTokenizer->strBufLen, advance);
    133    aTokenizer->strBufLen += advance;
    134    return advance;
    135  }
    136 
    137  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementCdataSection(
    138      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    139      int32_t endPos) {
    140    return mozilla::htmlaccel::AccelerateCdataSectionFastest(buf + pos,
    141                                                             buf + endPos);
    142  }
    143 
    144  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementPlaintext(
    145      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    146      int32_t endPos) {
    147    return mozilla::htmlaccel::AcceleratePlaintextFastest(buf + pos,
    148                                                          buf + endPos);
    149  }
    150 
    151  MOZ_ALWAYS_INLINE_EVEN_DEBUG static char16_t checkChar(
    152      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos) {
    153    return buf[pos];
    154  }
    155 
    156  MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentCarriageReturn(
    157      nsHtml5Tokenizer* aTokenizer) {
    158    aTokenizer->lastCR = true;
    159  }
    160 
    161  MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentLineFeed(
    162      nsHtml5Tokenizer* aTokenizer) {}
    163 };
    164 
    165 /**
    166 * This policy does not report tokenizer transitions anywhere. To be used
    167 * when _not_ viewing source and when not parsing innerHTML (or other
    168 * script execution-preventing fragment).
    169 */
    170 struct nsHtml5LineColPolicySIMD {
    171  static const bool reportErrors = false;
    172  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t transition(
    173      nsHtml5Highlighter* aHighlighter, int32_t aState, bool aReconsume,
    174      int32_t aPos) {
    175    return aState;
    176  }
    177  MOZ_ALWAYS_INLINE_EVEN_DEBUG static void completedNamedCharacterReference(
    178      nsHtml5Highlighter* aHighlighter) {}
    179 
    180  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementData(
    181      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    182      int32_t endPos) {
    183    // We need to check bounds for the `buf[pos]` access below to be OK.
    184    // Instead of just checking that `pos` isn't equal to `endPos`, let's
    185    // check that have at least one SIMD stride of data in the same branch,
    186    // since if we don't have at least one SIMD stride of data, we don't
    187    // need to proceed.
    188    if (endPos - pos < 16) {
    189      return 0;
    190    }
    191    char16_t c = buf[pos];
    192    if (c == '<' || c == '\n') {
    193      // Quickly handle the case where there is one tag immediately
    194      // after another and the very first thing in the data state is a
    195      // less-than sign and the case where a tag is immediately followed
    196      // by a line feed.
    197      return 0;
    198    }
    199    int32_t advance =
    200        mozilla::htmlaccel::AccelerateDataLineCol(buf + pos, buf + endPos);
    201    if (!advance) {
    202      // When the SIMD advance is zero, don't touch the line and col tracking.
    203      return 0;
    204    }
    205    if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
    206      // By changing the line and column here instead
    207      // of doing so eagerly when seeing the line break
    208      // causes the line break itself to be considered
    209      // column-wise at the end of a line.
    210      aTokenizer->line++;
    211      aTokenizer->col = advance;
    212      aTokenizer->nextCharOnNewLine = false;
    213    } else {
    214      aTokenizer->col += advance;
    215    }
    216    return advance;
    217  }
    218 
    219  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementRawtext(
    220      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    221      int32_t endPos) {
    222    // We need to check bounds for the `buf[pos]` access below to be OK.
    223    // Instead of just checking that `pos` isn't equal to `endPos`, let's
    224    // check that have at least one SIMD stride of data in the same branch,
    225    // since if we don't have at least one SIMD stride of data, we don't
    226    // need to proceed.
    227    if (endPos - pos < 16) {
    228      return 0;
    229    }
    230    char16_t c = buf[pos];
    231    if (c == '<' || c == '\n') {
    232      // Quickly handle the case where there is one tag immediately
    233      // after another and the very first thing in the data is a
    234      // less-than sign and the case where a tag is immediately followed
    235      // by a line feed.
    236      return 0;
    237    }
    238    int32_t advance =
    239        mozilla::htmlaccel::AccelerateRawtextLineCol(buf + pos, buf + endPos);
    240    if (!advance) {
    241      // When the SIMD advance is zero, don't touch the line and col tracking.
    242      return 0;
    243    }
    244    if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
    245      // By changing the line and column here instead
    246      // of doing so eagerly when seeing the line break
    247      // causes the line break itself to be considered
    248      // column-wise at the end of a line.
    249      aTokenizer->line++;
    250      aTokenizer->col = advance;
    251      aTokenizer->nextCharOnNewLine = false;
    252    } else {
    253      aTokenizer->col += advance;
    254    }
    255    return advance;
    256  }
    257 
    258  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
    259  accelerateAdvancementScriptDataEscaped(nsHtml5Tokenizer* aTokenizer,
    260                                         char16_t* buf, int32_t pos,
    261                                         int32_t endPos) {
    262    // This state shares the SIMD part with the comment state, but this
    263    // wrapper needs to differ!
    264    int32_t advance =
    265        mozilla::htmlaccel::AccelerateCommentLineCol(buf + pos, buf + endPos);
    266    if (!advance) {
    267      // When the SIMD advance is zero, don't touch the line and col tracking.
    268      return 0;
    269    }
    270    if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
    271      // By changing the line and column here instead
    272      // of doing so eagerly when seeing the line break
    273      // causes the line break itself to be considered
    274      // column-wise at the end of a line.
    275      aTokenizer->line++;
    276      aTokenizer->col = advance;
    277      aTokenizer->nextCharOnNewLine = false;
    278    } else {
    279      aTokenizer->col += advance;
    280    }
    281    return advance;
    282  }
    283 
    284  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementComment(
    285      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    286      int32_t endPos) {
    287    int32_t len = endPos - pos;
    288    int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
    289    if (len > strBufAvailable) {
    290      MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
    291      len = strBufAvailable;
    292    }
    293    int32_t advance = mozilla::htmlaccel::AccelerateCommentLineCol(
    294        buf + pos, buf + pos + len);
    295    if (!advance) {
    296      // When the SIMD advance is zero, don't touch the line and col tracking.
    297      return 0;
    298    }
    299    if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
    300      // By changing the line and column here instead
    301      // of doing so eagerly when seeing the line break
    302      // causes the line break itself to be considered
    303      // column-wise at the end of a line.
    304      aTokenizer->line++;
    305      aTokenizer->col = advance;
    306      aTokenizer->nextCharOnNewLine = false;
    307    } else {
    308      aTokenizer->col += advance;
    309    }
    310    // States that on the non-SIMD path copy characters to strBuf also
    311    // need to do that in the SIMD case.
    312    nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
    313                                aTokenizer->strBufLen, advance);
    314    aTokenizer->strBufLen += advance;
    315    return advance;
    316  }
    317 
    318  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
    319  accelerateAdvancementAttributeValueSingleQuoted(nsHtml5Tokenizer* aTokenizer,
    320                                                  char16_t* buf, int32_t pos,
    321                                                  int32_t endPos) {
    322    int32_t len = endPos - pos;
    323    int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
    324    if (len > strBufAvailable) {
    325      MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
    326      len = strBufAvailable;
    327    }
    328    int32_t advance =
    329        mozilla::htmlaccel::AccelerateAttributeValueSingleQuotedLineCol(
    330            buf + pos, buf + pos + len);
    331    if (!advance) {
    332      // When the SIMD advance is zero, don't touch the line and col tracking.
    333      return 0;
    334    }
    335    if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
    336      // By changing the line and column here instead
    337      // of doing so eagerly when seeing the line break
    338      // causes the line break itself to be considered
    339      // column-wise at the end of a line.
    340      aTokenizer->line++;
    341      aTokenizer->col = advance;
    342      aTokenizer->nextCharOnNewLine = false;
    343    } else {
    344      aTokenizer->col += advance;
    345    }
    346    // States that on the non-SIMD path copy characters to strBuf also
    347    // need to do that in the SIMD case.
    348    nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
    349                                aTokenizer->strBufLen, advance);
    350    aTokenizer->strBufLen += advance;
    351    return advance;
    352  }
    353 
    354  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
    355  accelerateAdvancementAttributeValueDoubleQuoted(nsHtml5Tokenizer* aTokenizer,
    356                                                  char16_t* buf, int32_t pos,
    357                                                  int32_t endPos) {
    358    int32_t len = endPos - pos;
    359    int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
    360    if (len > strBufAvailable) {
    361      MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
    362      len = strBufAvailable;
    363    }
    364    int32_t advance =
    365        mozilla::htmlaccel::AccelerateAttributeValueDoubleQuotedLineCol(
    366            buf + pos, buf + pos + len);
    367    if (!advance) {
    368      // When the SIMD advance is zero, don't touch the line and col tracking.
    369      return 0;
    370    }
    371    if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
    372      // By changing the line and column here instead
    373      // of doing so eagerly when seeing the line break
    374      // causes the line break itself to be considered
    375      // column-wise at the end of a line.
    376      aTokenizer->line++;
    377      aTokenizer->col = advance;
    378      aTokenizer->nextCharOnNewLine = false;
    379    } else {
    380      aTokenizer->col += advance;
    381    }
    382    // States that on the non-SIMD path copy characters to strBuf also
    383    // need to do that in the SIMD case.
    384    nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
    385                                aTokenizer->strBufLen, advance);
    386    aTokenizer->strBufLen += advance;
    387    return advance;
    388  }
    389 
    390  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementCdataSection(
    391      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    392      int32_t endPos) {
    393    int32_t advance = mozilla::htmlaccel::AccelerateCdataSectionLineCol(
    394        buf + pos, buf + endPos);
    395    if (!advance) {
    396      // When the SIMD advance is zero, don't touch the line and col tracking.
    397      return 0;
    398    }
    399    if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
    400      // By changing the line and column here instead
    401      // of doing so eagerly when seeing the line break
    402      // causes the line break itself to be considered
    403      // column-wise at the end of a line.
    404      aTokenizer->line++;
    405      aTokenizer->col = advance;
    406      aTokenizer->nextCharOnNewLine = false;
    407    } else {
    408      aTokenizer->col += advance;
    409    }
    410    return advance;
    411  }
    412 
    413  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementPlaintext(
    414      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    415      int32_t endPos) {
    416    int32_t advance =
    417        mozilla::htmlaccel::AcceleratePlaintextLineCol(buf + pos, buf + endPos);
    418    if (!advance) {
    419      // When the SIMD advance is zero, don't touch the line and col tracking.
    420      return 0;
    421    }
    422    if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
    423      // By changing the line and column here instead
    424      // of doing so eagerly when seeing the line break
    425      // causes the line break itself to be considered
    426      // column-wise at the end of a line.
    427      aTokenizer->line++;
    428      aTokenizer->col = advance;
    429      aTokenizer->nextCharOnNewLine = false;
    430    } else {
    431      aTokenizer->col += advance;
    432    }
    433    return advance;
    434  }
    435 
    436  MOZ_ALWAYS_INLINE_EVEN_DEBUG static char16_t checkChar(
    437      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos) {
    438    // The name of this method comes from the validator.
    439    // We aren't checking a char here. We read the next
    440    // UTF-16 code unit and, before returning it, adjust
    441    // the line and column numbers.
    442    char16_t c = buf[pos];
    443    if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
    444      // By changing the line and column here instead
    445      // of doing so eagerly when seeing the line break
    446      // causes the line break itself to be considered
    447      // column-wise at the end of a line.
    448      aTokenizer->line++;
    449      aTokenizer->col = 1;
    450      aTokenizer->nextCharOnNewLine = false;
    451    } else if (MOZ_LIKELY(!NS_IS_LOW_SURROGATE(c))) {
    452      // SpiderMonkey wants to count scalar values
    453      // instead of UTF-16 code units. We omit low
    454      // surrogates from the count so that only the
    455      // high surrogate increments the count for
    456      // two-code-unit scalar values.
    457      //
    458      // It's somewhat questionable from the performance
    459      // perspective to make the human-perceivable column
    460      // count correct for non-BMP characters in the case
    461      // where there is a single scalar value per extended
    462      // grapheme cluster when even on the BMP there are
    463      // various cases where the scalar count doesn't make
    464      // much sense as a human-perceived "column count" due
    465      // to extended grapheme clusters consisting of more
    466      // than one scalar value.
    467      aTokenizer->col++;
    468    }
    469    return c;
    470  }
    471 
    472  MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentCarriageReturn(
    473      nsHtml5Tokenizer* aTokenizer) {
    474    aTokenizer->nextCharOnNewLine = true;
    475    aTokenizer->lastCR = true;
    476  }
    477 
    478  MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentLineFeed(
    479      nsHtml5Tokenizer* aTokenizer) {
    480    aTokenizer->nextCharOnNewLine = true;
    481  }
    482 };
    483 
    484 /**
    485 * This policy reports the tokenizer transitions to a highlighter. To be used
    486 * when viewing source.
    487 */
    488 struct nsHtml5ViewSourcePolicySIMD {
    489  static const bool reportErrors = true;
    490  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t transition(
    491      nsHtml5Highlighter* aHighlighter, int32_t aState, bool aReconsume,
    492      int32_t aPos) {
    493    return aHighlighter->Transition(aState, aReconsume, aPos);
    494  }
    495  MOZ_ALWAYS_INLINE_EVEN_DEBUG static void completedNamedCharacterReference(
    496      nsHtml5Highlighter* aHighlighter) {
    497    aHighlighter->CompletedNamedCharacterReference();
    498  }
    499 
    500  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementData(
    501      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    502      int32_t endPos) {
    503    // We need to check bounds for the `buf[pos]` access below to be OK.
    504    // Instead of just checking that `pos` isn't equal to `endPos`, let's
    505    // check that have at least one SIMD stride of data in the same branch,
    506    // since if we don't have at least one SIMD stride of data, we don't
    507    // need to proceed.
    508    if (endPos - pos < 16) {
    509      return 0;
    510    }
    511    char16_t c = buf[pos];
    512    if (c == '<' || c == '\n') {
    513      // Quickly handle the case where there is one tag immediately
    514      // after another and the very first thing in the data state is a
    515      // less-than sign and the case where a tag is immediately followed
    516      // by a line feed.
    517      return 0;
    518    }
    519    return mozilla::htmlaccel::AccelerateDataViewSource(buf + pos,
    520                                                        buf + endPos);
    521  }
    522 
    523  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementRawtext(
    524      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    525      int32_t endPos) {
    526    // We need to check bounds for the `buf[pos]` access below to be OK.
    527    // Instead of just checking that `pos` isn't equal to `endPos`, let's
    528    // check that have at least one SIMD stride of data in the same branch,
    529    // since if we don't have at least one SIMD stride of data, we don't
    530    // need to proceed.
    531    if (endPos - pos < 16) {
    532      return 0;
    533    }
    534    char16_t c = buf[pos];
    535    if (c == '<' || c == '\n') {
    536      // Quickly handle the case where there is one tag immediately
    537      // after another and the very first thing in the state is a
    538      // less-than sign and the case where a tag is immediately followed
    539      // by a line feed.
    540      return 0;
    541    }
    542    return mozilla::htmlaccel::AccelerateRawtextViewSource(buf + pos,
    543                                                           buf + endPos);
    544  }
    545 
    546  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
    547  accelerateAdvancementScriptDataEscaped(nsHtml5Tokenizer* aTokenizer,
    548                                         char16_t* buf, int32_t pos,
    549                                         int32_t endPos) {
    550    // This state shares the SIMD part with the comment state, but this
    551    // wrapper needs to differ!
    552    return mozilla::htmlaccel::AccelerateCommentViewSource(buf + pos,
    553                                                           buf + endPos);
    554  }
    555 
    556  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementComment(
    557      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    558      int32_t endPos) {
    559    int32_t len = endPos - pos;
    560    int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
    561    if (len > strBufAvailable) {
    562      MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
    563      len = strBufAvailable;
    564    }
    565    int32_t advance = mozilla::htmlaccel::AccelerateCommentViewSource(
    566        buf + pos, buf + pos + len);
    567    // States that on the non-SIMD path copy characters to strBuf also
    568    // need to do that in the SIMD case.
    569    nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
    570                                aTokenizer->strBufLen, advance);
    571    aTokenizer->strBufLen += advance;
    572    return advance;
    573  }
    574 
    575  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
    576  accelerateAdvancementAttributeValueSingleQuoted(nsHtml5Tokenizer* aTokenizer,
    577                                                  char16_t* buf, int32_t pos,
    578                                                  int32_t endPos) {
    579    int32_t len = endPos - pos;
    580    int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
    581    if (len > strBufAvailable) {
    582      MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
    583      len = strBufAvailable;
    584    }
    585    int32_t advance =
    586        mozilla::htmlaccel::AccelerateAttributeValueSingleQuotedViewSource(
    587            buf + pos, buf + pos + len);
    588    // States that on the non-SIMD path copy characters to strBuf also
    589    // need to do that in the SIMD case.
    590    nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
    591                                aTokenizer->strBufLen, advance);
    592    aTokenizer->strBufLen += advance;
    593    return advance;
    594  }
    595 
    596  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
    597  accelerateAdvancementAttributeValueDoubleQuoted(nsHtml5Tokenizer* aTokenizer,
    598                                                  char16_t* buf, int32_t pos,
    599                                                  int32_t endPos) {
    600    int32_t len = endPos - pos;
    601    int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
    602    if (len > strBufAvailable) {
    603      MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
    604      len = strBufAvailable;
    605    }
    606    int32_t advance =
    607        mozilla::htmlaccel::AccelerateAttributeValueDoubleQuotedViewSource(
    608            buf + pos, buf + pos + len);
    609    // States that on the non-SIMD path copy characters to strBuf also
    610    // need to do that in the SIMD case.
    611    nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
    612                                aTokenizer->strBufLen, advance);
    613    aTokenizer->strBufLen += advance;
    614    return advance;
    615  }
    616 
    617  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementCdataSection(
    618      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    619      int32_t endPos) {
    620    return mozilla::htmlaccel::AccelerateCdataSectionViewSource(buf + pos,
    621                                                                buf + endPos);
    622  }
    623 
    624  MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementPlaintext(
    625      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
    626      int32_t endPos) {
    627    return mozilla::htmlaccel::AcceleratePlaintextViewSource(buf + pos,
    628                                                             buf + endPos);
    629  }
    630 
    631  MOZ_ALWAYS_INLINE_EVEN_DEBUG static char16_t checkChar(
    632      nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos) {
    633    return buf[pos];
    634  }
    635 
    636  MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentCarriageReturn(
    637      nsHtml5Tokenizer* aTokenizer) {
    638    aTokenizer->line++;
    639    aTokenizer->lastCR = true;
    640  }
    641 
    642  MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentLineFeed(
    643      nsHtml5Tokenizer* aTokenizer) {
    644    aTokenizer->line++;
    645  }
    646 };
    647 
    648 #endif  // nsHtml5TokenizerLoopPoliciesSIMD_h