author | Tooru Fujisawa <arai_a@mac.com> |
Wed, 10 Aug 2016 22:26:07 +0900 | |
changeset 308831 | 494760e727953aa80b28fb948ff1d8fc6196ba4b |
parent 308830 | bdfe71b2abc66b2a875f49e10c5557c354748e77 |
child 308832 | 9286619fafa0907c79c0f4ac712ca09d10ddc4b5 |
push id | 80449 |
push user | arai_a@mac.com |
push date | Wed, 10 Aug 2016 13:27:36 +0000 |
treeherder | mozilla-inbound@a9b2065fa983 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 1016936 |
milestone | 51.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -11621,16 +11621,32 @@ CodeGenerator::visitCheckReturn(LCheckRe Label bail, noChecks; masm.branchTestObject(Assembler::Equal, returnValue, &noChecks); masm.branchTestUndefined(Assembler::NotEqual, returnValue, &bail); masm.branchTestMagicValue(Assembler::Equal, thisValue, JS_UNINITIALIZED_LEXICAL, &bail); bailoutFrom(&bail, ins->snapshot()); 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); static const VMFunction ThrowObjectCoercibleInfo = FunctionInfo<ThrowObjCoercibleFn>(ThrowObjectCoercible, "ThrowObjectCoercible"); void CodeGenerator::visitCheckObjCoercible(LCheckObjCoercible* ins) { ValueOperand checkValue = ToValue(ins, LCheckObjCoercible::CheckValue);
--- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -368,16 +368,17 @@ class CodeGenerator final : public CodeG void visitAsmJSVoidReturn(LAsmJSVoidReturn* ret); void visitLexicalCheck(LLexicalCheck* ins); void visitThrowRuntimeLexicalError(LThrowRuntimeLexicalError* ins); void visitGlobalNameConflictsCheck(LGlobalNameConflictsCheck* ins); void visitDebugger(LDebugger* ins); void visitNewTarget(LNewTarget* ins); void visitArrowNewTarget(LArrowNewTarget* ins); void visitCheckReturn(LCheckReturn* ins); + void visitCheckIsObj(LCheckIsObj* ins); void visitCheckObjCoercible(LCheckObjCoercible* ins); void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins); void visitCheckOverRecursed(LCheckOverRecursed* lir); void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool); void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir); void visitOutOfLineUnboxFloatingPoint(OutOfLineUnboxFloatingPoint* ool);
--- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -2140,16 +2140,19 @@ IonBuilder::inspectOpcode(JSOp op) } // Just fall through to the unsupported bytecode case. break; case JSOP_NEWTARGET: return jsop_newtarget(); + case JSOP_CHECKISOBJ: + return jsop_checkisobj(GET_UINT8(pc)); + case JSOP_CHECKOBJCOERCIBLE: return jsop_checkobjcoercible(); case JSOP_DEBUGCHECKSELFHOSTED: { #ifdef DEBUG MDebugCheckSelfHosted* check = MDebugCheckSelfHosted::New(alloc(), current->pop()); current->add(check); @@ -10790,16 +10793,32 @@ IonBuilder::jsop_rest() // elements added. MSetInitializedLength* initLength = MSetInitializedLength::New(alloc(), elements, index); current->add(initLength); 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() { MDefinition* toCheck = current->peek(-1); if (!toCheck->mightBeType(MIRType::Undefined) && !toCheck->mightBeType(MIRType::Null)) { toCheck->setImplicitlyUsedUnchecked();
--- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -775,16 +775,17 @@ class IonBuilder MOZ_MUST_USE bool jsop_isnoiter(); MOZ_MUST_USE bool jsop_iterend(); MOZ_MUST_USE bool jsop_in(); MOZ_MUST_USE bool jsop_instanceof(); MOZ_MUST_USE bool jsop_getaliasedvar(ScopeCoordinate sc); 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. */ enum InliningStatus { InliningStatus_Error, InliningStatus_NotInlined,
--- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -4564,16 +4564,28 @@ LIRGenerator::visitCheckReturn(MCheckRet LCheckReturn* lir = new(alloc()) LCheckReturn(useBoxAtStart(retVal), useBoxAtStart(thisVal)); assignSnapshot(lir, Bailout_BadDerivedConstructorReturn); add(lir, 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) { MDefinition* checkVal = ins->checkValue(); MOZ_ASSERT(checkVal->type() == MIRType::Value); LCheckObjCoercible* lir = new(alloc()) LCheckObjCoercible(useBoxAtStart(checkVal)); redefine(ins, checkVal); add(lir, ins);
--- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -312,16 +312,17 @@ class LIRGenerator : public LIRGenerator void visitThrowRuntimeLexicalError(MThrowRuntimeLexicalError* ins); void visitGlobalNameConflictsCheck(MGlobalNameConflictsCheck* ins); void visitDebugger(MDebugger* ins); void visitNewTarget(MNewTarget* ins); void visitArrowNewTarget(MArrowNewTarget* ins); void visitAtomicIsLockFree(MAtomicIsLockFree* ins); void visitGuardSharedTypedArray(MGuardSharedTypedArray* ins); void visitCheckReturn(MCheckReturn* ins); + void visitCheckIsObj(MCheckIsObj* ins); void visitCheckObjCoercible(MCheckObjCoercible* ins); void visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins); }; } // namespace jit } // namespace js #endif /* jit_Lowering_h */
--- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -13045,33 +13045,58 @@ class MAtomicTypedArrayElementBinop class MDebugger : public MNullaryInstruction { public: INSTRUCTION_HEADER(Debugger) 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 { explicit MCheckObjCoercible(MDefinition* toCheck) : MUnaryInstruction(toCheck) { setGuard(); setResultType(MIRType::Value); setResultTypeSet(toCheck->resultTypeSet()); } public: INSTRUCTION_HEADER(CheckObjCoercible) TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, checkValue)) - }; class MDebugCheckSelfHosted : public MUnaryInstruction, public BoxInputsPolicy::Data { explicit MDebugCheckSelfHosted(MDefinition* toCheck) : MUnaryInstruction(toCheck)
--- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -297,16 +297,17 @@ namespace jit { _(UnknownValue) \ _(LexicalCheck) \ _(ThrowRuntimeLexicalError) \ _(GlobalNameConflictsCheck) \ _(Debugger) \ _(NewTarget) \ _(ArrowNewTarget) \ _(CheckReturn) \ + _(CheckIsObj) \ _(CheckObjCoercible) \ _(DebugCheckSelfHosted) // Forward declarations of MIR types. #define FORWARD_DECLARE(op) class M##op; MIR_OPCODE_LIST(FORWARD_DECLARE) #undef FORWARD_DECLARE
--- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -8691,16 +8691,32 @@ class LCheckReturn : public LCallInstruc setBoxOperand(ReturnValue, retVal); setBoxOperand(ThisValue, thisVal); } static const size_t ReturnValue = 0; 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> { public: LIR_HEADER(CheckObjCoercible) static const size_t CheckValue = 0; explicit LCheckObjCoercible(const LBoxAllocation& value) {
--- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -422,12 +422,13 @@ _(AssertResultT) \ _(LexicalCheck) \ _(ThrowRuntimeLexicalError) \ _(GlobalNameConflictsCheck) \ _(Debugger) \ _(NewTarget) \ _(ArrowNewTarget) \ _(CheckReturn) \ + _(CheckIsObj) \ _(CheckObjCoercible) \ _(DebugCheckSelfHosted) #endif /* jit_shared_LOpcodes_shared_h */