mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 784765 - Add fastpath for string equality with different length. r=jandem
This commit is contained in:
parent
860a3dc1e2
commit
b2ff782bd9
@ -1920,6 +1920,7 @@ CodeGenerator::visitCompareS(LCompareS *lir)
|
||||
Register left = ToRegister(lir->left());
|
||||
Register right = ToRegister(lir->right());
|
||||
Register output = ToRegister(lir->output());
|
||||
Register temp = ToRegister(lir->temp());
|
||||
|
||||
typedef bool (*pf)(JSContext *, HandleString, HandleString, JSBool *);
|
||||
static const VMFunction stringsEqualInfo = FunctionInfo<pf>(ion::StringsEqual<true>);
|
||||
@ -1943,20 +1944,26 @@ CodeGenerator::visitCompareS(LCompareS *lir)
|
||||
masm.jump(ool->rejoin());
|
||||
|
||||
masm.bind(¬PointerEqual);
|
||||
masm.loadPtr(Address(left, JSString::offsetOfLengthAndFlags()), output);
|
||||
masm.loadPtr(Address(right, JSString::offsetOfLengthAndFlags()), temp);
|
||||
|
||||
// JSString::isAtom === !(lengthAndFlags & ATOM_MASK)
|
||||
Imm32 atomMask(JSString::ATOM_BIT);
|
||||
|
||||
// This optimization is only correct for atomized strings,
|
||||
// so we need to jump to the ool path.
|
||||
masm.branchTest32(Assembler::Zero, Address(left, JSString::offsetOfLengthAndFlags()),
|
||||
atomMask, ool->entry());
|
||||
|
||||
masm.branchTest32(Assembler::Zero, Address(right, JSString::offsetOfLengthAndFlags()),
|
||||
atomMask, ool->entry());
|
||||
Label notAtom;
|
||||
// We can optimize the equality operation to a pointer compare for
|
||||
// two atoms.
|
||||
Imm32 atomBit(JSString::ATOM_BIT);
|
||||
masm.branchTest32(Assembler::Zero, output, atomBit, ¬Atom);
|
||||
masm.branchTest32(Assembler::Zero, temp, atomBit, ¬Atom);
|
||||
|
||||
masm.cmpPtr(left, right);
|
||||
emitSet(JSOpToCondition(op), output);
|
||||
masm.jump(ool->rejoin());
|
||||
|
||||
masm.bind(¬Atom);
|
||||
// Strings of different length can never be equal.
|
||||
masm.rshiftPtr(Imm32(JSString::LENGTH_SHIFT), output);
|
||||
masm.rshiftPtr(Imm32(JSString::LENGTH_SHIFT), temp);
|
||||
masm.branchPtr(Assembler::Equal, output, temp, ool->entry());
|
||||
masm.move32(Imm32(op == JSOP_NE || op == JSOP_STRICTNE), output);
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
return true;
|
||||
|
@ -930,13 +930,15 @@ class LCompareD : public LInstructionHelper<1, 2, 0>
|
||||
}
|
||||
};
|
||||
|
||||
class LCompareS : public LInstructionHelper<1, 2, 0>
|
||||
class LCompareS : public LInstructionHelper<1, 2, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(CompareS);
|
||||
LCompareS(const LAllocation &left, const LAllocation &right) {
|
||||
LCompareS(const LAllocation &left, const LAllocation &right,
|
||||
const LDefinition &temp) {
|
||||
setOperand(0, left);
|
||||
setOperand(1, right);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
|
||||
const LAllocation *left() {
|
||||
@ -945,6 +947,9 @@ class LCompareS : public LInstructionHelper<1, 2, 0>
|
||||
const LAllocation *right() {
|
||||
return getOperand(1);
|
||||
}
|
||||
const LDefinition *temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
MCompare *mir() {
|
||||
return mir_->toCompare();
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ LIRGenerator::visitCompare(MCompare *comp)
|
||||
// LCompareSAndBranch. Doing this now wouldn't be wrong, but doesn't
|
||||
// make sense and avoids confusion.
|
||||
if (comp->specialization() == MIRType_String) {
|
||||
LCompareS *lir = new LCompareS(useRegister(left), useRegister(right));
|
||||
LCompareS *lir = new LCompareS(useRegister(left), useRegister(right), temp());
|
||||
if (!define(lir, comp))
|
||||
return false;
|
||||
return assignSafepoint(lir, comp);
|
||||
|
Loading…
Reference in New Issue
Block a user