Bug 1542736 - Part 4: Replace JS_UNDEC with js::AsciiDigitToNumber. r=jwalden

js::AsciiDigitToNumber is an optimised version of mozilla::AsciiAlphanumericToNumber
for known ASCII digit-only cases, which avoids the extra comparisons for ASCII
alphabetical characters. This ensures replacing JS_UNDEC with js::AsciiDigitToNumber
still emits the same assembly.

Differential Revision: https://phabricator.services.mozilla.com/D26507

--HG--
extra : moz-landing-system : lando
This commit is contained in:
André Bargull 2019-04-11 11:35:06 +00:00
Родитель 0a02337b5b
Коммит db7c7bb385
6 изменённых файлов: 18 добавлений и 16 удалений

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

@ -227,7 +227,7 @@ static bool StringIsArrayIndexHelper(const CharT* s, uint32_t length,
}
uint32_t c = 0, previous = 0;
uint32_t index = JS7_UNDEC(*s++);
uint32_t index = AsciiDigitToNumber(*s++);
/* Don't allow leading zeros. */
if (index == 0 && s != end) {
@ -240,7 +240,7 @@ static bool StringIsArrayIndexHelper(const CharT* s, uint32_t length,
}
previous = index;
c = JS7_UNDEC(*s);
c = AsciiDigitToNumber(*s);
index = 10 * index + c;
}

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

@ -1245,7 +1245,7 @@ static bool InterpretDollar(JSLinearString* matched, JSLinearString* string,
char16_t c = currentDollar[1];
if (IsAsciiDigit(c)) {
/* $n, $nn */
unsigned num = JS7_UNDEC(c);
unsigned num = AsciiDigitToNumber(c);
if (num > captures.length()) {
// The result is implementation-defined, do not substitute.
return false;
@ -1255,7 +1255,7 @@ static bool InterpretDollar(JSLinearString* matched, JSLinearString* string,
if (currentChar < replacementEnd) {
c = *currentChar;
if (IsAsciiDigit(c)) {
unsigned tmpNum = 10 * num + JS7_UNDEC(c);
unsigned tmpNum = 10 * num + AsciiDigitToNumber(c);
// If num > captures.length(), the result is implementation-defined.
// Consume next character only if num <= captures.length().
if (tmpNum <= captures.length()) {

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

@ -17,6 +17,7 @@
#include <stdint.h>
#include <stdio.h>
#include <string>
#include <type_traits>
#include "jsutil.h"
#include "NamespaceImports.h"
@ -27,13 +28,6 @@
class JSLinearString;
/*
* Shorthands for ASCII (7-bit) decimal and hex conversion.
* Manually inline isdigit and isxdigit for performance; MSVC doesn't do this
* for us.
*/
#define JS7_UNDEC(c) ((c) - '0')
static MOZ_ALWAYS_INLINE size_t js_strlen(const char16_t* s) {
return std::char_traits<char16_t>::length(s);
}
@ -48,6 +42,13 @@ namespace js {
class StringBuffer;
template <typename CharT>
constexpr uint8_t AsciiDigitToNumber(CharT c) {
using UnsignedCharT = std::make_unsigned_t<CharT>;
auto uc = static_cast<UnsignedCharT>(c);
return uc - '0';
}
template <typename Char1, typename Char2>
inline bool EqualChars(const Char1* s1, const Char2* s2, size_t len) {
return mozilla::ArrayEqual(s1, s2, len);

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

@ -14,6 +14,7 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Sprintf.h"
#include "mozilla/TextUtils.h"
#include "mozilla/Unused.h"
#include <ctype.h>
@ -738,7 +739,7 @@ bool ExpandErrorArgumentsHelper(JSContext* cx, JSErrorCallback callback,
while (*fmt) {
if (*fmt == '{') {
if (isdigit(fmt[1])) {
int d = JS7_UNDEC(fmt[1]);
int d = AsciiDigitToNumber(fmt[1]);
MOZ_RELEASE_ASSERT(d < args.count());
strncpy(out, args.args(d), args.lengths(d));
out += args.lengths(d);

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

@ -1095,14 +1095,14 @@ bool JSFlatString::isIndexSlow(const CharT* s, size_t length,
RangedPtr<const CharT> cp(s, length + 1);
const RangedPtr<const CharT> end(s + length, s, length + 1);
uint32_t index = JS7_UNDEC(*cp++);
uint32_t index = AsciiDigitToNumber(*cp++);
uint32_t oldIndex = 0;
uint32_t c = 0;
if (index != 0) {
while (IsAsciiDigit(*cp)) {
oldIndex = index;
c = JS7_UNDEC(*cp);
c = AsciiDigitToNumber(*cp);
index = 10 * index + c;
cp++;
}

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

@ -2316,7 +2316,7 @@ bool js::StringIsTypedArrayIndex(const CharT* s, size_t length,
}
uint64_t index = 0;
uint32_t digit = JS7_UNDEC(*s++);
uint32_t digit = AsciiDigitToNumber(*s++);
/* Don't allow leading zeros. */
if (digit == 0 && s != end) {
@ -2330,7 +2330,7 @@ bool js::StringIsTypedArrayIndex(const CharT* s, size_t length,
return false;
}
digit = JS7_UNDEC(*s);
digit = AsciiDigitToNumber(*s);
/* Watch for overflows. */
if ((UINT64_MAX - digit) / 10 < index) {