Backed out 3 changesets (bug 1698791) for causing valgrind failures.

Backed out changeset 1bd16d8959e5 (bug 1698791)
Backed out changeset 467a7afcdd3d (bug 1698791)
Backed out changeset 48b921d8aeee (bug 1698791)
This commit is contained in:
Cosmin Sabou 2021-03-22 20:55:29 +02:00
Родитель 0583e7e496
Коммит f29929310e
12 изменённых файлов: 110 добавлений и 116 удалений

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

@ -223,20 +223,57 @@ static MOZ_ALWAYS_INLINE bool GetLengthProperty(JSContext* cx, HandleObject obj,
* "08" or "4.0" as array indices, which they are not.
*
*/
template <typename CharT>
static bool StringIsArrayIndexHelper(const CharT* s, uint32_t length,
uint32_t* indexp) {
const CharT* end = s + length;
if (length == 0 || length > (sizeof("4294967294") - 1) || !IsAsciiDigit(*s)) {
return false;
}
uint32_t c = 0, previous = 0;
uint32_t index = AsciiDigitToNumber(*s++);
/* Don't allow leading zeros. */
if (index == 0 && s != end) {
return false;
}
for (; s < end; s++) {
if (!IsAsciiDigit(*s)) {
return false;
}
previous = index;
c = AsciiDigitToNumber(*s);
index = 10 * index + c;
}
/* Make sure we didn't overflow. */
if (previous < (MAX_ARRAY_INDEX / 10) ||
(previous == (MAX_ARRAY_INDEX / 10) && c <= (MAX_ARRAY_INDEX % 10))) {
MOZ_ASSERT(index <= MAX_ARRAY_INDEX);
*indexp = index;
return true;
}
return false;
}
JS_FRIEND_API bool js::StringIsArrayIndex(JSLinearString* str,
uint32_t* indexp) {
return str->isIndex(indexp) && *indexp <= MAX_ARRAY_INDEX;
AutoCheckCannotGC nogc;
return str->hasLatin1Chars()
? StringIsArrayIndexHelper(str->latin1Chars(nogc), str->length(),
indexp)
: StringIsArrayIndexHelper(str->twoByteChars(nogc), str->length(),
indexp);
}
JS_FRIEND_API bool js::StringIsArrayIndex(const char16_t* str, uint32_t length,
uint32_t* indexp) {
if (length == 0 || length > UINT32_CHAR_BUFFER_LENGTH) {
return false;
}
if (!mozilla::IsAsciiDigit(str[0])) {
return false;
}
return CheckStringIsIndex(str, length, indexp) && *indexp <= MAX_ARRAY_INDEX;
return StringIsArrayIndexHelper(str, length, indexp);
}
template <typename T>

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

@ -37,7 +37,12 @@ MOZ_ALWAYS_INLINE bool IdIsIndex(jsid id, uint32_t* indexp) {
}
JSAtom* atom = JSID_TO_ATOM(id);
return atom->isIndex(indexp) && *indexp <= MAX_ARRAY_INDEX;
if (atom->length() == 0 ||
!mozilla::IsAsciiDigit(atom->latin1OrTwoByteChar(0))) {
return false;
}
return js::StringIsArrayIndex(atom, indexp);
}
// The methods below only create dense boxed arrays.

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

@ -336,7 +336,8 @@ static bool ValueToNameOrSymbolId(JSContext* cx, HandleValue idVal,
return true;
}
if (id.isAtom() && id.toAtom()->isIndex()) {
uint32_t dummy;
if (id.isAtom() && id.toAtom()->isIndex(&dummy)) {
id.set(JSID_VOID);
return true;
}

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

@ -12111,7 +12111,8 @@ void CodeGenerator::addGetPropertyCache(LInstruction* ins,
CacheKind kind = CacheKind::GetElem;
if (id.constant() && id.value().isString()) {
JSString* idString = id.value().toString();
if (idString->isAtom() && !idString->asAtom().isIndex()) {
uint32_t dummy;
if (idString->isAtom() && !idString->asAtom().isIndex(&dummy)) {
kind = CacheKind::GetProp;
}
}
@ -12128,7 +12129,8 @@ void CodeGenerator::addSetPropertyCache(LInstruction* ins,
CacheKind kind = CacheKind::SetElem;
if (id.constant() && id.value().isString()) {
JSString* idString = id.value().toString();
if (idString->isAtom() && !idString->asAtom().isIndex()) {
uint32_t dummy;
if (idString->isAtom() && !idString->asAtom().isIndex(&dummy)) {
kind = CacheKind::SetProp;
}
}
@ -12176,7 +12178,8 @@ void CodeGenerator::visitGetPropSuperCache(LGetPropSuperCache* ins) {
CacheKind kind = CacheKind::GetElemSuper;
if (id.constant() && id.value().isString()) {
JSString* idString = id.value().toString();
if (idString->isAtom() && !idString->asAtom().isIndex()) {
uint32_t dummy;
if (idString->isAtom() && !idString->asAtom().isIndex(&dummy)) {
kind = CacheKind::GetPropSuper;
}
}

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

@ -1165,7 +1165,7 @@ int32_t GetIndexFromString(JSString* str) {
return -1;
}
uint32_t index;
uint32_t index = UINT32_MAX;
if (!str->asLinear().isIndex(&index) || index > INT32_MAX) {
return -1;
}

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

@ -5431,7 +5431,9 @@ JS_PUBLIC_API bool JS_CharsToId(JSContext* cx, JS::TwoByteChars chars,
return false;
}
#ifdef DEBUG
MOZ_ASSERT(!atom->isIndex(), "API misuse: |chars| must not encode an index");
uint32_t dummy;
MOZ_ASSERT(!atom->isIndex(&dummy),
"API misuse: |chars| must not encode an index");
#endif
idp.set(AtomToId(atom));
return true;

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

@ -818,7 +818,7 @@ JSLinearString* js::Int32ToString(JSContext* cx, int32_t si) {
return nullptr;
}
if (si >= 0) {
str->maybeInitializeIndexValue(si);
str->maybeInitializeIndex(si);
}
CacheNumber(cx, si, str);
@ -1660,7 +1660,7 @@ static JSString* NumberToStringWithBase(JSContext* cx, double d, int base) {
}
if (isBase10Int && i >= 0) {
s->maybeInitializeIndexValue(i);
s->maybeInitializeIndex(i);
}
realm->dtoaCache.cache(base, d, s);

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

@ -518,7 +518,11 @@ bool ArgumentsObject::obj_mayResolve(const JSAtomState& names, jsid id,
// Arguments might resolve indexes, Symbol.iterator, or length/callee.
if (JSID_IS_ATOM(id)) {
JSAtom* atom = JSID_TO_ATOM(id);
return atom->isIndex() || atom == names.length || atom == names.callee;
uint32_t index;
if (atom->isIndex(&index)) {
return true;
}
return atom == names.length || atom == names.callee;
}
return id.isInt() || id.isWellKnownSymbol(JS::SymbolCode::iterator);

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

@ -20,7 +20,7 @@
namespace js {
MOZ_ALWAYS_INLINE jsid AtomToId(JSAtom* atom) {
inline jsid AtomToId(JSAtom* atom) {
static_assert(JSID_INT_MIN == 0);
uint32_t index;

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

@ -954,14 +954,7 @@ static MOZ_ALWAYS_INLINE JSAtom* AllocateNewAtom(
MOZ_ASSERT(atom->hash() == lookup.hash);
if (indexValue) {
atom->setIsIndex(*indexValue);
} else {
// We need to call isIndexSlow directly to avoid the flag check in isIndex,
// because we still have to initialize that flag.
uint32_t index;
if (atom->isIndexSlow(&index)) {
atom->setIsIndex(index);
}
atom->maybeInitializeIndex(*indexValue, true);
}
return atom;

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

@ -1230,40 +1230,17 @@ template bool js::CheckStringIsIndex(const char16_t* s, size_t length,
uint32_t* indexp);
template <typename CharT>
static uint32_t AtomCharsToIndex(const CharT* s, size_t length) {
// Chars are known to be a valid index value (as determined by
// CheckStringIsIndex) that didn't fit in the "index value" bits in the
// header.
MOZ_ASSERT(length > 0);
MOZ_ASSERT(length <= UINT32_CHAR_BUFFER_LENGTH);
RangedPtr<const CharT> cp(s, length);
const RangedPtr<const CharT> end(s + length, s, length);
MOZ_ASSERT(IsAsciiDigit(*cp));
uint32_t index = AsciiDigitToNumber(*cp++);
MOZ_ASSERT(index != 0);
while (cp < end) {
MOZ_ASSERT(IsAsciiDigit(*cp));
index = 10 * index + AsciiDigitToNumber(*cp);
cp++;
}
return index;
/* static */
bool JSLinearString::isIndexSlow(const CharT* s, size_t length,
uint32_t* indexp) {
return js::CheckStringIsIndex(s, length, indexp);
}
uint32_t JSAtom::getIndexSlow() const {
MOZ_ASSERT(isIndex());
MOZ_ASSERT(!hasIndexValue());
template bool JSLinearString::isIndexSlow(const Latin1Char* s, size_t length,
uint32_t* indexp);
size_t len = length();
AutoCheckCannotGC nogc;
return hasLatin1Chars() ? AtomCharsToIndex(latin1Chars(nogc), len)
: AtomCharsToIndex(twoByteChars(nogc), len);
}
template bool JSLinearString::isIndexSlow(const char16_t* s, size_t length,
uint32_t* indexp);
constexpr StaticStrings::SmallCharTable StaticStrings::createSmallCharTable() {
SmallCharTable array{};
@ -1328,7 +1305,7 @@ bool StaticStrings::init(JSContext* cx) {
// Static string initialization can not race, so allow even without the
// lock.
intStaticTable[i]->setIsIndex(i);
intStaticTable[i]->maybeInitializeIndex(i, true);
}
return true;

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

@ -61,12 +61,6 @@ class PropertyName;
/* The buffer length required to contain any unsigned 32-bit integer. */
static const size_t UINT32_CHAR_BUFFER_LENGTH = sizeof("4294967295") - 1;
// Returns true if the characters of `s` store an unsigned 32-bit integer value,
// initializing `*indexp` to that value if so.
// Leading '0' isn't allowed except 0 itself.
template <typename CharT>
bool CheckStringIsIndex(const CharT* s, size_t length, uint32_t* indexp);
} /* namespace js */
// clang-format off
@ -311,20 +305,16 @@ class JSString : public js::gc::CellWithLengthAndFlags {
static const uint32_t LATIN1_CHARS_BIT = js::Bit(9);
// Whether this atom's characters store an uint32 index value. Not used for
// non-atomized strings. See JSLinearString::isIndex.
static const uint32_t ATOM_IS_INDEX = js::Bit(10);
static const uint32_t INDEX_VALUE_BIT = js::Bit(11);
static const uint32_t INDEX_VALUE_BIT = js::Bit(10);
static const uint32_t INDEX_VALUE_SHIFT = 16;
// NON_DEDUP_BIT is used in string deduplication during tenuring.
static const uint32_t NON_DEDUP_BIT = js::Bit(12);
static const uint32_t NON_DEDUP_BIT = js::Bit(11);
// If IN_STRING_TO_ATOM_CACHE is set, this string had an entry in the
// StringToAtomCache at some point. Note that GC can purge the cache without
// clearing this bit.
static const uint32_t IN_STRING_TO_ATOM_CACHE = js::Bit(13);
static const uint32_t IN_STRING_TO_ATOM_CACHE = js::Bit(12);
static const uint32_t MAX_LENGTH = JS::MaxStringLength;
@ -785,6 +775,9 @@ class JSLinearString : public JSString {
bool isLinear() const = delete;
JSLinearString& asLinear() const = delete;
template <typename CharT>
static bool isIndexSlow(const CharT* s, size_t length, uint32_t* indexp);
protected:
/* Returns void pointer to latin1/twoByte chars, for finalizers. */
MOZ_ALWAYS_INLINE
@ -871,11 +864,10 @@ class JSLinearString : public JSString {
JS::AutoCheckCannotGC nogc;
if (hasLatin1Chars()) {
const JS::Latin1Char* s = latin1Chars(nogc);
return mozilla::IsAsciiDigit(*s) &&
js::CheckStringIsIndex(s, len, indexp);
return mozilla::IsAsciiDigit(*s) && isIndexSlow(s, len, indexp);
}
const char16_t* s = twoByteChars(nogc);
return mozilla::IsAsciiDigit(*s) && js::CheckStringIsIndex(s, len, indexp);
return mozilla::IsAsciiDigit(*s) && isIndexSlow(s, len, indexp);
}
/*
@ -885,9 +877,18 @@ class JSLinearString : public JSString {
* (Thus if calling isIndex returns true, js::IndexToString(cx, *indexp) will
* be a string equal to this string.)
*/
inline bool isIndex(uint32_t* indexp) const;
bool isIndex(uint32_t* indexp) const {
MOZ_ASSERT(JSString::isLinear());
void maybeInitializeIndexValue(uint32_t index, bool allowAtom = false) {
if (JSString::hasIndexValue()) {
*indexp = getIndexValue();
return true;
}
return isIndexSlow(indexp);
}
void maybeInitializeIndex(uint32_t index, bool allowAtom = false) {
MOZ_ASSERT(JSString::isLinear());
MOZ_ASSERT_IF(hasIndexValue(), getIndexValue() == index);
MOZ_ASSERT_IF(!allowAtom, !isAtom());
@ -1163,29 +1164,6 @@ class JSAtom : public JSLinearString {
setFlagBit(PERMANENT_ATOM_MASK);
}
MOZ_ALWAYS_INLINE bool isIndex() const {
MOZ_ASSERT(JSString::isAtom());
mozilla::DebugOnly<uint32_t> index;
MOZ_ASSERT(!!(flags() & ATOM_IS_INDEX) == isIndexSlow(&index));
return flags() & ATOM_IS_INDEX;
}
MOZ_ALWAYS_INLINE bool isIndex(uint32_t* index) const {
MOZ_ASSERT(JSString::isAtom());
if (!isIndex()) {
return false;
}
*index = hasIndexValue() ? getIndexValue() : getIndexSlow();
return true;
}
uint32_t getIndexSlow() const;
void setIsIndex(uint32_t index) {
MOZ_ASSERT(JSString::isAtom());
setFlagBit(ATOM_IS_INDEX);
maybeInitializeIndexValue(index, /* allowAtom = */ true);
}
inline js::HashNumber hash() const;
inline void initHash(js::HashNumber hash);
@ -1266,6 +1244,12 @@ MOZ_ALWAYS_INLINE JSAtom* JSLinearString::morphAtomizedStringIntoPermanentAtom(
namespace js {
// Returns true if the characters of `s` store an unsigned 32-bit integer value,
// initializing `*indexp` to that value if so.
// Leading '0' isn't allowed except 0 itself.
template <typename CharT>
bool CheckStringIsIndex(const CharT* s, size_t length, uint32_t* indexp);
/**
* An indexable characters class exposing unaligned, little-endian encoded
* char16_t data.
@ -1989,25 +1973,13 @@ MOZ_ALWAYS_INLINE const char16_t* JSLinearString::rawTwoByteChars() const {
}
inline js::PropertyName* JSAtom::asPropertyName() {
MOZ_ASSERT(!isIndex());
#ifdef DEBUG
uint32_t dummy;
MOZ_ASSERT(!isIndex(&dummy));
#endif
return static_cast<js::PropertyName*>(this);
}
inline bool JSLinearString::isIndex(uint32_t* indexp) const {
MOZ_ASSERT(JSString::isLinear());
if (isAtom()) {
return asAtom().isIndex(indexp);
}
if (JSString::hasIndexValue()) {
*indexp = getIndexValue();
return true;
}
return isIndexSlow(indexp);
}
inline size_t JSLinearString::allocSize() const {
MOZ_ASSERT(ownsMallocedChars());