Bug 1331136 - Handle more StringChar cases with ropes in CacheIR. r=jandem

This commit is contained in:
Tom Schuster 2017-03-15 14:05:08 +01:00
Родитель 162864127d
Коммит c4dfa17e82
6 изменённых файлов: 50 добавлений и 13 удалений

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

@ -1217,10 +1217,26 @@ GetPropIRGenerator::tryAttachStringChar(ValOperandId valId, ValOperandId indexId
if (!val_.isString())
return false;
JSString* str = val_.toString();
int32_t index = idVal_.toInt32();
if (size_t(index) >= str->length() ||
!str->isLinear() ||
if (index < 0)
return false;
JSString* str = val_.toString();
if (size_t(index) >= str->length())
return false;
// This follows JSString::getChar, otherwise we fail to attach getChar in a lot of cases.
if (str->isRope()) {
JSRope* rope = &str->asRope();
// Make sure the left side contains the index.
if (size_t(index) >= rope->leftChild()->length())
return false;
str = rope->leftChild();
}
if (!str->isLinear() ||
str->asLinear().latin1OrTwoByteChar(index) >= StaticStrings::UNIT_STATIC_LIMIT)
{
return false;

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

@ -1758,12 +1758,10 @@ CacheIRCompiler::emitLoadStringCharResult()
if (!addFailurePath(&failure))
return false;
masm.branchIfRope(str, failure->label());
// Bounds check, load string char.
masm.branch32(Assembler::BelowOrEqual, Address(str, JSString::offsetOfLength()),
index, failure->label());
masm.loadStringChar(str, index, scratch1);
masm.loadStringChar(str, index, scratch1, failure->label());
// Load StaticString for this char.
masm.branch32(Assembler::AboveOrEqual, scratch1, Imm32(StaticStrings::UNIT_STATIC_LIMIT),

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

@ -7966,10 +7966,7 @@ CodeGenerator::visitCharCodeAt(LCharCodeAt* lir)
Register output = ToRegister(lir->output());
OutOfLineCode* ool = oolCallVM(CharCodeAtInfo, lir, ArgList(str, index), StoreRegisterTo(output));
masm.branchIfRope(str, ool->entry());
masm.loadStringChar(str, index, output);
masm.loadStringChar(str, index, output, ool->entry());
masm.bind(ool->rejoin());
}

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

@ -395,6 +395,14 @@ MacroAssembler::branchIfRope(Register str, Label* label)
branchTest32(Assembler::Zero, flags, Imm32(JSString::TYPE_FLAGS_MASK), label);
}
void
MacroAssembler::branchIfNotRope(Register str, Label* label)
{
Address flags(str, JSString::offsetOfFlags());
static_assert(JSString::ROPE_FLAGS == 0, "Rope type flags must be 0");
branchTest32(Assembler::NonZero, flags, Imm32(JSString::TYPE_FLAGS_MASK), label);
}
void
MacroAssembler::branchLatin1String(Register string, Label* label)
{

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

@ -1383,12 +1383,29 @@ MacroAssembler::loadStringChars(Register str, Register dest)
}
void
MacroAssembler::loadStringChar(Register str, Register index, Register output)
MacroAssembler::loadStringChar(Register str, Register index, Register output, Label* fail)
{
MOZ_ASSERT(str != output);
MOZ_ASSERT(index != output);
loadStringChars(str, output);
movePtr(str, output);
// This follows JSString::getChar.
Label notRope;
branchIfNotRope(str, &notRope);
// Load leftChild.
loadPtr(Address(str, JSRope::offsetOfLeft()), output);
// Check if the index is contained in the leftChild.
// Todo: Handle index in the rightChild.
branch32(Assembler::BelowOrEqual, Address(output, JSString::offsetOfLength()), index, fail);
// If the left side is another rope, give up.
branchIfRope(output, fail);
bind(&notRope);
loadStringChars(output, output);
Label isLatin1, done;
branchLatin1String(str, &isLatin1);

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

@ -1113,6 +1113,7 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchIfTrueBool(Register reg, Label* label);
inline void branchIfRope(Register str, Label* label);
inline void branchIfNotRope(Register str, Label* label);
inline void branchLatin1String(Register string, Label* label);
inline void branchTwoByteString(Register string, Label* label);
@ -1493,7 +1494,7 @@ class MacroAssembler : public MacroAssemblerSpecific
}
void loadStringChars(Register str, Register dest);
void loadStringChar(Register str, Register index, Register output);
void loadStringChar(Register str, Register index, Register output, Label* fail);
void loadJSContext(Register dest);
void loadJitActivation(Register dest) {