summaryrefslogtreecommitdiffstats
path: root/js/src/jit/MIR.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/jit/MIR.cpp87
1 files changed, 71 insertions, 16 deletions
diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp
index a74406567b..f826fbd987 100644
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -1122,11 +1122,16 @@ MConstant::MConstant(TempAllocator& alloc, const js::Value& vp)
case MIRType::Double:
payload_.d = vp.toDouble();
break;
- case MIRType::String:
- MOZ_ASSERT(!IsInsideNursery(vp.toString()));
- MOZ_ASSERT(vp.toString()->isLinear());
+ case MIRType::String: {
+ JSString* str = vp.toString();
+ if (str->isAtomRef()) {
+ str = str->atom();
+ }
+ MOZ_ASSERT(!IsInsideNursery(str));
+ MOZ_ASSERT(str->isAtom());
payload_.str = vp.toString();
break;
+ }
case MIRType::Symbol:
payload_.sym = vp.toSymbol();
break;
@@ -4310,11 +4315,56 @@ static JSType TypeOfName(JSLinearString* str) {
return JSTYPE_LIMIT;
}
-static mozilla::Maybe<std::pair<MTypeOfName*, JSType>> IsTypeOfCompare(
- MCompare* ins) {
+struct TypeOfCompareInput {
+ // The `typeof expr` side of the comparison.
+ // MTypeOfName for JSOp::Typeof/JSOp::TypeofExpr, and
+ // MTypeOf for JSOp::TypeofEq (same pointer as typeOf).
+ MDefinition* typeOfSide;
+
+ // The actual `typeof` operation.
+ MTypeOf* typeOf;
+
+ // The string side of the comparison.
+ JSType type;
+
+ // True if the comparison uses raw JSType (Generated for JSOp::TypeofEq).
+ bool isIntComparison;
+
+ TypeOfCompareInput(MDefinition* typeOfSide, MTypeOf* typeOf, JSType type,
+ bool isIntComparison)
+ : typeOfSide(typeOfSide),
+ typeOf(typeOf),
+ type(type),
+ isIntComparison(isIntComparison) {}
+};
+
+static mozilla::Maybe<TypeOfCompareInput> IsTypeOfCompare(MCompare* ins) {
if (!IsEqualityOp(ins->jsop())) {
return mozilla::Nothing();
}
+
+ if (ins->compareType() == MCompare::Compare_Int32) {
+ auto* lhs = ins->lhs();
+ auto* rhs = ins->rhs();
+
+ if (ins->type() != MIRType::Boolean || lhs->type() != MIRType::Int32 ||
+ rhs->type() != MIRType::Int32) {
+ return mozilla::Nothing();
+ }
+
+ // NOTE: The comparison is generated inside JIT, and typeof should always
+ // be in the LHS.
+ if (!lhs->isTypeOf() || !rhs->isConstant()) {
+ return mozilla::Nothing();
+ }
+
+ auto* typeOf = lhs->toTypeOf();
+ auto* constant = rhs->toConstant();
+
+ JSType type = JSType(constant->toInt32());
+ return mozilla::Some(TypeOfCompareInput(typeOf, typeOf, type, true));
+ }
+
if (ins->compareType() != MCompare::Compare_String) {
return mozilla::Nothing();
}
@@ -4335,21 +4385,21 @@ static mozilla::Maybe<std::pair<MTypeOfName*, JSType>> IsTypeOfCompare(
auto* typeOfName =
lhs->isTypeOfName() ? lhs->toTypeOfName() : rhs->toTypeOfName();
- MOZ_ASSERT(typeOfName->input()->isTypeOf());
+ auto* typeOf = typeOfName->input()->toTypeOf();
auto* constant = lhs->isConstant() ? lhs->toConstant() : rhs->toConstant();
JSType type = TypeOfName(&constant->toString()->asLinear());
- return mozilla::Some(std::pair(typeOfName, type));
+ return mozilla::Some(TypeOfCompareInput(typeOfName, typeOf, type, false));
}
bool MCompare::tryFoldTypeOf(bool* result) {
- auto typeOfPair = IsTypeOfCompare(this);
- if (!typeOfPair) {
+ auto typeOfCompare = IsTypeOfCompare(this);
+ if (!typeOfCompare) {
return false;
}
- auto [typeOfName, type] = *typeOfPair;
- auto* typeOf = typeOfName->input()->toTypeOf();
+ auto* typeOf = typeOfCompare->typeOf;
+ JSType type = typeOfCompare->type;
switch (type) {
case JSTYPE_BOOLEAN:
@@ -4639,12 +4689,12 @@ bool MCompare::evaluateConstantOperands(TempAllocator& alloc, bool* result) {
}
MDefinition* MCompare::tryFoldTypeOf(TempAllocator& alloc) {
- auto typeOfPair = IsTypeOfCompare(this);
- if (!typeOfPair) {
+ auto typeOfCompare = IsTypeOfCompare(this);
+ if (!typeOfCompare) {
return this;
}
- auto [typeOfName, type] = *typeOfPair;
- auto* typeOf = typeOfName->input()->toTypeOf();
+ auto* typeOf = typeOfCompare->typeOf;
+ JSType type = typeOfCompare->type;
auto* input = typeOf->input();
MOZ_ASSERT(input->type() == MIRType::Value ||
@@ -4676,10 +4726,15 @@ MDefinition* MCompare::tryFoldTypeOf(TempAllocator& alloc) {
// In that case it'd more efficient to emit MTypeOf compared to MTypeOfIs. We
// don't yet handle that case, because it'd require a separate optimization
// pass to correctly detect it.
- if (typeOfName->hasOneUse()) {
+ if (typeOfCompare->typeOfSide->hasOneUse()) {
return MTypeOfIs::New(alloc, input, jsop(), type);
}
+ if (typeOfCompare->isIntComparison) {
+ // Already optimized.
+ return this;
+ }
+
MConstant* cst = MConstant::New(alloc, Int32Value(type));
block()->insertBefore(this, cst);