Bug 1016936 - Part 3: Support JSOP_CHECKISOBJ in Ion. r=jandem

This commit is contained in:
Tooru Fujisawa 2016-08-10 22:26:07 +09:00
Родитель 726a539a34
Коммит 453cda5798
10 изменённых файлов: 94 добавлений и 1 удалений

Просмотреть файл

@ -11626,6 +11626,22 @@ CodeGenerator::visitCheckReturn(LCheckReturn* ins)
masm.bind(&noChecks); masm.bind(&noChecks);
} }
typedef bool (*ThrowCheckIsObjectFn)(JSContext*, CheckIsObjectKind);
static const VMFunction ThrowCheckIsObjectInfo =
FunctionInfo<ThrowCheckIsObjectFn>(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); typedef bool (*ThrowObjCoercibleFn)(JSContext*, HandleValue);
static const VMFunction ThrowObjectCoercibleInfo = static const VMFunction ThrowObjectCoercibleInfo =
FunctionInfo<ThrowObjCoercibleFn>(ThrowObjectCoercible, "ThrowObjectCoercible"); FunctionInfo<ThrowObjCoercibleFn>(ThrowObjectCoercible, "ThrowObjectCoercible");

Просмотреть файл

@ -373,6 +373,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitNewTarget(LNewTarget* ins); void visitNewTarget(LNewTarget* ins);
void visitArrowNewTarget(LArrowNewTarget* ins); void visitArrowNewTarget(LArrowNewTarget* ins);
void visitCheckReturn(LCheckReturn* ins); void visitCheckReturn(LCheckReturn* ins);
void visitCheckIsObj(LCheckIsObj* ins);
void visitCheckObjCoercible(LCheckObjCoercible* ins); void visitCheckObjCoercible(LCheckObjCoercible* ins);
void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins); void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins);

Просмотреть файл

@ -2145,6 +2145,9 @@ IonBuilder::inspectOpcode(JSOp op)
case JSOP_NEWTARGET: case JSOP_NEWTARGET:
return jsop_newtarget(); return jsop_newtarget();
case JSOP_CHECKISOBJ:
return jsop_checkisobj(GET_UINT8(pc));
case JSOP_CHECKOBJCOERCIBLE: case JSOP_CHECKOBJCOERCIBLE:
return jsop_checkobjcoercible(); return jsop_checkobjcoercible();
@ -10794,6 +10797,22 @@ IonBuilder::jsop_rest()
return true; 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 bool
IonBuilder::jsop_checkobjcoercible() IonBuilder::jsop_checkobjcoercible()
{ {

Просмотреть файл

@ -780,6 +780,7 @@ class IonBuilder
MOZ_MUST_USE bool jsop_setaliasedvar(ScopeCoordinate sc); MOZ_MUST_USE bool jsop_setaliasedvar(ScopeCoordinate sc);
MOZ_MUST_USE bool jsop_debugger(); MOZ_MUST_USE bool jsop_debugger();
MOZ_MUST_USE bool jsop_newtarget(); MOZ_MUST_USE bool jsop_newtarget();
MOZ_MUST_USE bool jsop_checkisobj(uint8_t kind);
MOZ_MUST_USE bool jsop_checkobjcoercible(); MOZ_MUST_USE bool jsop_checkobjcoercible();
/* Inlining. */ /* Inlining. */

Просмотреть файл

@ -4568,6 +4568,18 @@ LIRGenerator::visitCheckReturn(MCheckReturn* ins)
redefine(ins, retVal); 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 void
LIRGenerator::visitCheckObjCoercible(MCheckObjCoercible* ins) LIRGenerator::visitCheckObjCoercible(MCheckObjCoercible* ins)
{ {

Просмотреть файл

@ -317,6 +317,7 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitAtomicIsLockFree(MAtomicIsLockFree* ins); void visitAtomicIsLockFree(MAtomicIsLockFree* ins);
void visitGuardSharedTypedArray(MGuardSharedTypedArray* ins); void visitGuardSharedTypedArray(MGuardSharedTypedArray* ins);
void visitCheckReturn(MCheckReturn* ins); void visitCheckReturn(MCheckReturn* ins);
void visitCheckIsObj(MCheckIsObj* ins);
void visitCheckObjCoercible(MCheckObjCoercible* ins); void visitCheckObjCoercible(MCheckObjCoercible* ins);
void visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins); void visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins);
}; };

Просмотреть файл

@ -13050,6 +13050,32 @@ class MDebugger : public MNullaryInstruction
TRIVIAL_NEW_WRAPPERS 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 class MCheckObjCoercible
: public MUnaryInstruction, : public MUnaryInstruction,
public BoxInputsPolicy::Data public BoxInputsPolicy::Data
@ -13066,7 +13092,6 @@ class MCheckObjCoercible
INSTRUCTION_HEADER(CheckObjCoercible) INSTRUCTION_HEADER(CheckObjCoercible)
TRIVIAL_NEW_WRAPPERS TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, checkValue)) NAMED_OPERANDS((0, checkValue))
}; };
class MDebugCheckSelfHosted class MDebugCheckSelfHosted

Просмотреть файл

@ -302,6 +302,7 @@ namespace jit {
_(NewTarget) \ _(NewTarget) \
_(ArrowNewTarget) \ _(ArrowNewTarget) \
_(CheckReturn) \ _(CheckReturn) \
_(CheckIsObj) \
_(CheckObjCoercible) \ _(CheckObjCoercible) \
_(DebugCheckSelfHosted) _(DebugCheckSelfHosted)

Просмотреть файл

@ -8696,6 +8696,22 @@ class LCheckReturn : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0
static const size_t ThisValue = BOX_PIECES; static const size_t ThisValue = BOX_PIECES;
}; };
class LCheckIsObj : public LInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
{
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<BOX_PIECES, BOX_PIECES, 0> class LCheckObjCoercible : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
{ {
public: public:

Просмотреть файл

@ -427,6 +427,7 @@
_(NewTarget) \ _(NewTarget) \
_(ArrowNewTarget) \ _(ArrowNewTarget) \
_(CheckReturn) \ _(CheckReturn) \
_(CheckIsObj) \
_(CheckObjCoercible) \ _(CheckObjCoercible) \
_(DebugCheckSelfHosted) _(DebugCheckSelfHosted)