зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1689311: Don't box BigInt for MTest and MNot. r=jandem!
Differential Revision: https://phabricator.services.mozilla.com/D103298
This commit is contained in:
Родитель
0d128ebbfd
Коммит
43774473a1
|
@ -1474,6 +1474,21 @@ void CodeGenerator::testValueTruthy(const ValueOperand& value,
|
|||
masm.jump(ifTruthy);
|
||||
}
|
||||
|
||||
void CodeGenerator::visitTestBIAndBranch(LTestBIAndBranch* lir) {
|
||||
Label* ifTrueLabel = getJumpLabelForBranch(lir->ifTrue());
|
||||
Label* ifFalseLabel = getJumpLabelForBranch(lir->ifFalse());
|
||||
Register input = ToRegister(lir->input());
|
||||
|
||||
if (isNextBlock(lir->ifFalse()->lir())) {
|
||||
masm.branchIfBigIntIsNonZero(input, ifTrueLabel);
|
||||
} else if (isNextBlock(lir->ifTrue()->lir())) {
|
||||
masm.branchIfBigIntIsZero(input, ifFalseLabel);
|
||||
} else {
|
||||
masm.branchIfBigIntIsZero(input, ifFalseLabel);
|
||||
jumpToBlock(lir->ifTrue());
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenerator::visitTestOAndBranch(LTestOAndBranch* lir) {
|
||||
Label* truthy = getJumpLabelForBranch(lir->ifTruthy());
|
||||
Label* falsy = getJumpLabelForBranch(lir->ifFalsy());
|
||||
|
@ -10248,6 +10263,14 @@ void CodeGenerator::visitSetInitializedLength(LSetInitializedLength* lir) {
|
|||
SetLengthFromIndex(masm, lir->index(), initLength);
|
||||
}
|
||||
|
||||
void CodeGenerator::visitNotBI(LNotBI* lir) {
|
||||
Register input = ToRegister(lir->input());
|
||||
Register output = ToRegister(lir->output());
|
||||
|
||||
masm.cmp32Set(Assembler::Equal, Address(input, BigInt::offsetOfLength()),
|
||||
Imm32(0), output);
|
||||
}
|
||||
|
||||
void CodeGenerator::visitNotO(LNotO* lir) {
|
||||
auto* ool = new (alloc()) OutOfLineTestObjectWithLabels();
|
||||
addOutOfLineCode(ool, lir->mir());
|
||||
|
|
|
@ -571,10 +571,6 @@ void LIRGenerator::visitTest(MTest* test) {
|
|||
// TestPolicy).
|
||||
MOZ_ASSERT(opd->type() != MIRType::String);
|
||||
|
||||
// BigInt is boxed in type analysis.
|
||||
MOZ_ASSERT(opd->type() != MIRType::BigInt,
|
||||
"BigInt should be boxed by TestPolicy");
|
||||
|
||||
// Testing a constant.
|
||||
if (MConstant* constant = opd->maybeConstantValue()) {
|
||||
bool b;
|
||||
|
@ -814,6 +810,9 @@ void LIRGenerator::visitTest(MTest* test) {
|
|||
add(new (alloc())
|
||||
LTestI64AndBranch(useInt64Register(opd), ifTrue, ifFalse));
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
add(new (alloc()) LTestBIAndBranch(useRegister(opd), ifTrue, ifFalse));
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Bad type");
|
||||
}
|
||||
|
@ -3008,13 +3007,13 @@ void LIRGenerator::visitNot(MNot* ins) {
|
|||
// String is converted to length of string in the type analysis phase (see
|
||||
// TestPolicy).
|
||||
MOZ_ASSERT(op->type() != MIRType::String);
|
||||
MOZ_ASSERT(op->type() != MIRType::BigInt,
|
||||
"BigInt should be boxed by TestPolicy");
|
||||
|
||||
// - boolean: x xor 1
|
||||
// - int32: LCompare(x, 0)
|
||||
// - double: LCompare(x, 0)
|
||||
// - null or undefined: true
|
||||
// - symbol: false
|
||||
// - bigint: LNotBI(x)
|
||||
// - object: false if it never emulates undefined, else LNotO(x)
|
||||
switch (op->type()) {
|
||||
case MIRType::Boolean: {
|
||||
|
@ -3042,6 +3041,9 @@ void LIRGenerator::visitNot(MNot* ins) {
|
|||
case MIRType::Symbol:
|
||||
define(new (alloc()) LInteger(0), ins);
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
define(new (alloc()) LNotBI(useRegisterAtStart(op)), ins);
|
||||
break;
|
||||
case MIRType::Object:
|
||||
define(new (alloc()) LNotO(useRegister(op)), ins);
|
||||
break;
|
||||
|
|
|
@ -279,6 +279,7 @@ bool TestPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins) const {
|
|||
case MIRType::Double:
|
||||
case MIRType::Float32:
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt:
|
||||
case MIRType::Object:
|
||||
break;
|
||||
|
||||
|
@ -290,8 +291,7 @@ bool TestPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins) const {
|
|||
}
|
||||
|
||||
default:
|
||||
ins->replaceOperand(0, BoxAt(alloc, ins, op));
|
||||
break;
|
||||
MOZ_CRASH("Unexpected MIRType.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1355,7 +1355,7 @@ class LTestI64AndBranch : public LControlInstructionHelper<2, INT64_PIECES, 0> {
|
|||
MBasicBlock* ifFalse() const { return getSuccessor(1); }
|
||||
};
|
||||
|
||||
// Takes in either an integer or boolean input and tests it for truthiness.
|
||||
// Takes in a double input and tests it for truthiness.
|
||||
class LTestDAndBranch : public LControlInstructionHelper<2, 1, 0> {
|
||||
public:
|
||||
LIR_HEADER(TestDAndBranch)
|
||||
|
@ -1372,7 +1372,7 @@ class LTestDAndBranch : public LControlInstructionHelper<2, 1, 0> {
|
|||
MBasicBlock* ifFalse() const { return getSuccessor(1); }
|
||||
};
|
||||
|
||||
// Takes in either an integer or boolean input and tests it for truthiness.
|
||||
// Takes in a float32 input and tests it for truthiness.
|
||||
class LTestFAndBranch : public LControlInstructionHelper<2, 1, 0> {
|
||||
public:
|
||||
LIR_HEADER(TestFAndBranch)
|
||||
|
@ -1389,6 +1389,23 @@ class LTestFAndBranch : public LControlInstructionHelper<2, 1, 0> {
|
|||
MBasicBlock* ifFalse() const { return getSuccessor(1); }
|
||||
};
|
||||
|
||||
// Takes in a bigint input and tests it for truthiness.
|
||||
class LTestBIAndBranch : public LControlInstructionHelper<2, 1, 0> {
|
||||
public:
|
||||
LIR_HEADER(TestBIAndBranch)
|
||||
|
||||
LTestBIAndBranch(const LAllocation& in, MBasicBlock* ifTrue,
|
||||
MBasicBlock* ifFalse)
|
||||
: LControlInstructionHelper(classOpcode) {
|
||||
setOperand(0, in);
|
||||
setSuccessor(0, ifTrue);
|
||||
setSuccessor(1, ifFalse);
|
||||
}
|
||||
|
||||
MBasicBlock* ifTrue() { return getSuccessor(0); }
|
||||
MBasicBlock* ifFalse() { return getSuccessor(1); }
|
||||
};
|
||||
|
||||
// Takes an object and tests it for truthiness. An object is falsy iff it
|
||||
// emulates |undefined|; see js::EmulatesUndefined.
|
||||
class LTestOAndBranch : public LControlInstructionHelper<2, 1, 1> {
|
||||
|
@ -1884,6 +1901,18 @@ class LNotF : public LInstructionHelper<1, 1, 0> {
|
|||
MNot* mir() { return mir_->toNot(); }
|
||||
};
|
||||
|
||||
// Not operation on a BigInt.
|
||||
class LNotBI : public LInstructionHelper<1, 1, 0> {
|
||||
public:
|
||||
LIR_HEADER(NotBI)
|
||||
|
||||
explicit LNotBI(const LAllocation& input) : LInstructionHelper(classOpcode) {
|
||||
setOperand(0, input);
|
||||
}
|
||||
|
||||
MNot* mir() { return mir_->toNot(); }
|
||||
};
|
||||
|
||||
// Boolean complement operation on an object.
|
||||
class LNotO : public LInstructionHelper<1, 1, 0> {
|
||||
public:
|
||||
|
|
Загрузка…
Ссылка в новой задаче