зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1101576 - IonMonkey: Add fixes for LSubstr, r=efaust
This commit is contained in:
Родитель
29e67251fe
Коммит
16ed739a5c
|
@ -0,0 +1,14 @@
|
|||
// Random chosen test: js/src/jit-test/tests/ion/bug928423.js
|
||||
o = {
|
||||
a: 1,
|
||||
b: 1
|
||||
}
|
||||
print(1);
|
||||
for (var x = 0; x < 2; x++) {
|
||||
print(2);
|
||||
o["a1".substr(0, 1)]
|
||||
o["b1".substr(0, 1)]
|
||||
}
|
||||
print(3);
|
||||
// jsfunfuzz
|
||||
"a" + "b"
|
|
@ -6058,6 +6058,8 @@ bool CodeGenerator::visitSubstr(LSubstr *lir)
|
|||
Register length = ToRegister(lir->length());
|
||||
Register output = ToRegister(lir->output());
|
||||
Register temp = ToRegister(lir->temp());
|
||||
Register temp2 = ToRegister(lir->temp2());
|
||||
Register temp3 = ToRegister(lir->temp3());
|
||||
Address stringFlags(string, JSString::offsetOfFlags());
|
||||
|
||||
Label isLatin1, notInline, nonZero, isInlinedLatin1;
|
||||
|
@ -6102,9 +6104,10 @@ bool CodeGenerator::visitSubstr(LSubstr *lir)
|
|||
Address(output, JSString::offsetOfFlags()));
|
||||
masm.computeEffectiveAddress(stringStorage, temp);
|
||||
BaseIndex chars(temp, begin, ScaleFromElemWidth(sizeof(char16_t)));
|
||||
masm.computeEffectiveAddress(chars, begin);
|
||||
masm.computeEffectiveAddress(chars, temp2);
|
||||
masm.computeEffectiveAddress(outputStorage, temp);
|
||||
CopyStringChars(masm, temp, begin, length, string, sizeof(char16_t), sizeof(char16_t));
|
||||
CopyStringChars(masm, temp, temp2, length, temp3, sizeof(char16_t), sizeof(char16_t));
|
||||
masm.load32(Address(output, JSString::offsetOfLength()), length);
|
||||
masm.store16(Imm32(0), Address(temp, 0));
|
||||
masm.jump(done);
|
||||
}
|
||||
|
@ -6112,11 +6115,12 @@ bool CodeGenerator::visitSubstr(LSubstr *lir)
|
|||
{
|
||||
masm.store32(Imm32(JSString::INIT_FAT_INLINE_FLAGS | JSString::LATIN1_CHARS_BIT),
|
||||
Address(output, JSString::offsetOfFlags()));
|
||||
masm.computeEffectiveAddress(stringStorage, temp);
|
||||
masm.computeEffectiveAddress(stringStorage, temp2);
|
||||
static_assert(sizeof(char) == 1, "begin index shouldn't need scaling");
|
||||
masm.addPtr(temp, begin);
|
||||
masm.addPtr(begin, temp2);
|
||||
masm.computeEffectiveAddress(outputStorage, temp);
|
||||
CopyStringChars(masm, temp, begin, length, string, sizeof(char), sizeof(char));
|
||||
CopyStringChars(masm, temp, temp2, length, temp3, sizeof(char), sizeof(char));
|
||||
masm.load32(Address(output, JSString::offsetOfLength()), length);
|
||||
masm.store8(Imm32(0), Address(temp, 0));
|
||||
masm.jump(done);
|
||||
}
|
||||
|
|
|
@ -3450,18 +3450,20 @@ class LStringSplit : public LCallInstructionHelper<1, 2, 0>
|
|||
}
|
||||
};
|
||||
|
||||
class LSubstr : public LInstructionHelper<1, 3, 1>
|
||||
class LSubstr : public LInstructionHelper<1, 3, 3>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(Substr)
|
||||
|
||||
LSubstr(const LAllocation &string, const LAllocation &begin, const LAllocation &length,
|
||||
const LDefinition &temp)
|
||||
const LDefinition &temp, const LDefinition &temp2, const LDefinition &temp3)
|
||||
{
|
||||
setOperand(0, string);
|
||||
setOperand(1, begin);
|
||||
setOperand(2, length);
|
||||
setTemp(0, temp);
|
||||
setTemp(1, temp2);
|
||||
setTemp(2, temp3);
|
||||
}
|
||||
const LAllocation *string() {
|
||||
return getOperand(0);
|
||||
|
@ -3475,6 +3477,12 @@ class LSubstr : public LInstructionHelper<1, 3, 1>
|
|||
const LDefinition *temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
const LDefinition *temp2() {
|
||||
return getTemp(1);
|
||||
}
|
||||
const LDefinition *temp3() {
|
||||
return getTemp(2);
|
||||
}
|
||||
const MStringSplit *mir() const {
|
||||
return mir_->toStringSplit();
|
||||
}
|
||||
|
|
|
@ -2184,10 +2184,15 @@ LIRGenerator::visitStringReplace(MStringReplace *ins)
|
|||
bool
|
||||
LIRGenerator::visitSubstr(MSubstr *ins)
|
||||
{
|
||||
LSubstr *lir = new (alloc()) LSubstr(useFixed(ins->string(), CallTempReg1),
|
||||
// The last temporary need to be a register that can handle 8bit moves, but
|
||||
// there is no way to signal that to register allocator, except to give a
|
||||
// fixed temporary that is able to do this.
|
||||
LSubstr *lir = new (alloc()) LSubstr(useRegister(ins->string()),
|
||||
useRegister(ins->begin()),
|
||||
useRegister(ins->length()),
|
||||
temp());
|
||||
temp(),
|
||||
temp(),
|
||||
tempFixed(CallTempReg1));
|
||||
return define(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче