diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 8602da66b638..40b3586c7120 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -11626,6 +11626,22 @@ CodeGenerator::visitCheckReturn(LCheckReturn* ins) masm.bind(&noChecks); } +typedef bool (*ThrowCheckIsObjectFn)(JSContext*, CheckIsObjectKind); +static const VMFunction ThrowCheckIsObjectInfo = + FunctionInfo(ThrowCheckIsObject, "ThrowCheckIsObject"); + +void +CodeGenerator::visitCheckIsObj(LCheckIsObj* ins) +{ + ValueOperand checkValue = ToValue(ins, LCheckIsObj::CheckValue); + + OutOfLineCode* ool = oolCallVM(ThrowCheckIsObjectInfo, ins, + ArgList(Imm32(ins->mir()->checkKind())), + StoreNothing()); + masm.branchTestObject(Assembler::NotEqual, checkValue, ool->entry()); + masm.bind(ool->rejoin()); +} + typedef bool (*ThrowObjCoercibleFn)(JSContext*, HandleValue); static const VMFunction ThrowObjectCoercibleInfo = FunctionInfo(ThrowObjectCoercible, "ThrowObjectCoercible"); diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 074bdecac131..f61c2d718019 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -373,6 +373,7 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitNewTarget(LNewTarget* ins); void visitArrowNewTarget(LArrowNewTarget* ins); void visitCheckReturn(LCheckReturn* ins); + void visitCheckIsObj(LCheckIsObj* ins); void visitCheckObjCoercible(LCheckObjCoercible* ins); void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 61508cf16096..33b76673ee6c 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -2145,6 +2145,9 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_NEWTARGET: return jsop_newtarget(); + case JSOP_CHECKISOBJ: + return jsop_checkisobj(GET_UINT8(pc)); + case JSOP_CHECKOBJCOERCIBLE: return jsop_checkobjcoercible(); @@ -10794,6 +10797,22 @@ IonBuilder::jsop_rest() return true; } +bool +IonBuilder::jsop_checkisobj(uint8_t kind) +{ + MDefinition* toCheck = current->peek(-1); + + if (toCheck->type() == MIRType::Object) { + toCheck->setImplicitlyUsedUnchecked(); + return true; + } + + MCheckIsObj* check = MCheckIsObj::New(alloc(), current->pop(), kind); + current->add(check); + current->push(check); + return true; +} + bool IonBuilder::jsop_checkobjcoercible() { diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index f0e0ad10ae72..4d6e4a5996c0 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -780,6 +780,7 @@ class IonBuilder MOZ_MUST_USE bool jsop_setaliasedvar(ScopeCoordinate sc); MOZ_MUST_USE bool jsop_debugger(); MOZ_MUST_USE bool jsop_newtarget(); + MOZ_MUST_USE bool jsop_checkisobj(uint8_t kind); MOZ_MUST_USE bool jsop_checkobjcoercible(); /* Inlining. */ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 19b455cbfea1..413cdf11a2f7 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -4568,6 +4568,18 @@ LIRGenerator::visitCheckReturn(MCheckReturn* ins) redefine(ins, retVal); } +void +LIRGenerator::visitCheckIsObj(MCheckIsObj* ins) +{ + MDefinition* checkVal = ins->checkValue(); + MOZ_ASSERT(checkVal->type() == MIRType::Value); + + LCheckIsObj* lir = new(alloc()) LCheckIsObj(useBoxAtStart(checkVal)); + redefine(ins, checkVal); + add(lir, ins); + assignSafepoint(lir, ins); +} + void LIRGenerator::visitCheckObjCoercible(MCheckObjCoercible* ins) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 9b8ab3ce8870..5e6207ee5972 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -317,6 +317,7 @@ class LIRGenerator : public LIRGeneratorSpecific void visitAtomicIsLockFree(MAtomicIsLockFree* ins); void visitGuardSharedTypedArray(MGuardSharedTypedArray* ins); void visitCheckReturn(MCheckReturn* ins); + void visitCheckIsObj(MCheckIsObj* ins); void visitCheckObjCoercible(MCheckObjCoercible* ins); void visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins); }; diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 0608013d8983..a0c3c3e8cd04 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -13050,6 +13050,32 @@ class MDebugger : public MNullaryInstruction TRIVIAL_NEW_WRAPPERS }; +class MCheckIsObj + : public MUnaryInstruction, + public BoxInputsPolicy::Data +{ + uint8_t checkKind_; + + explicit MCheckIsObj(MDefinition* toCheck, uint8_t checkKind) + : MUnaryInstruction(toCheck), checkKind_(checkKind) + { + setResultType(MIRType::Value); + setResultTypeSet(toCheck->resultTypeSet()); + setGuard(); + } + + public: + INSTRUCTION_HEADER(CheckIsObj) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, checkValue)) + + uint8_t checkKind() const { return checkKind_; } + + AliasSet getAliasSet() const override { + return AliasSet::None(); + } +}; + class MCheckObjCoercible : public MUnaryInstruction, public BoxInputsPolicy::Data @@ -13066,7 +13092,6 @@ class MCheckObjCoercible INSTRUCTION_HEADER(CheckObjCoercible) TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, checkValue)) - }; class MDebugCheckSelfHosted diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index 6fb1c31d70d3..76fae5cada4d 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -302,6 +302,7 @@ namespace jit { _(NewTarget) \ _(ArrowNewTarget) \ _(CheckReturn) \ + _(CheckIsObj) \ _(CheckObjCoercible) \ _(DebugCheckSelfHosted) diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index c60b58c639c8..b942e7c4a097 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -8696,6 +8696,22 @@ class LCheckReturn : public LCallInstructionHelper +{ + public: + LIR_HEADER(CheckIsObj) + + static const size_t CheckValue = 0; + + explicit LCheckIsObj(const LBoxAllocation& value) { + setBoxOperand(CheckValue, value); + } + + MCheckIsObj* mir() const { + return mir_->toCheckIsObj(); + } +}; + class LCheckObjCoercible : public LCallInstructionHelper { public: diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h index fffaa2df194d..2a7794d8aaa6 100644 --- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -427,6 +427,7 @@ _(NewTarget) \ _(ArrowNewTarget) \ _(CheckReturn) \ + _(CheckIsObj) \ _(CheckObjCoercible) \ _(DebugCheckSelfHosted)