michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef jit_CodeGenerator_h michael@0: #define jit_CodeGenerator_h michael@0: michael@0: #include "jit/IonCaches.h" michael@0: #if defined(JS_ION_PERF) michael@0: # include "jit/PerfSpewer.h" michael@0: #endif michael@0: michael@0: #if defined(JS_CODEGEN_X86) michael@0: # include "jit/x86/CodeGenerator-x86.h" michael@0: #elif defined(JS_CODEGEN_X64) michael@0: # include "jit/x64/CodeGenerator-x64.h" michael@0: #elif defined(JS_CODEGEN_ARM) michael@0: # include "jit/arm/CodeGenerator-arm.h" michael@0: #elif defined(JS_CODEGEN_MIPS) michael@0: # include "jit/mips/CodeGenerator-mips.h" michael@0: #else michael@0: #error "Unknown architecture!" michael@0: #endif michael@0: michael@0: namespace js { michael@0: namespace jit { michael@0: michael@0: class OutOfLineTestObject; michael@0: class OutOfLineNewArray; michael@0: class OutOfLineNewObject; michael@0: class CheckOverRecursedFailure; michael@0: class CheckOverRecursedFailurePar; michael@0: class OutOfLineInterruptCheckPar; michael@0: class OutOfLineInterruptCheckImplicit; michael@0: class OutOfLineUnboxFloatingPoint; michael@0: class OutOfLineStoreElementHole; michael@0: class OutOfLineTypeOfV; michael@0: class OutOfLineLoadTypedArray; michael@0: class OutOfLineNewGCThingPar; michael@0: class OutOfLineUpdateCache; michael@0: class OutOfLineCallPostWriteBarrier; michael@0: michael@0: class CodeGenerator : public CodeGeneratorSpecific michael@0: { michael@0: bool generateArgumentsChecks(bool bailout = true); michael@0: bool generateBody(); michael@0: michael@0: public: michael@0: CodeGenerator(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm = nullptr); michael@0: ~CodeGenerator(); michael@0: michael@0: public: michael@0: bool generate(); michael@0: bool generateAsmJS(Label *stackOverflowLabel); michael@0: bool link(JSContext *cx, types::CompilerConstraintList *constraints); michael@0: michael@0: bool visitLabel(LLabel *lir); michael@0: bool visitNop(LNop *lir); michael@0: bool visitOsiPoint(LOsiPoint *lir); michael@0: bool visitGoto(LGoto *lir); michael@0: bool visitTableSwitch(LTableSwitch *ins); michael@0: bool visitTableSwitchV(LTableSwitchV *ins); michael@0: bool visitCloneLiteral(LCloneLiteral *lir); michael@0: bool visitParameter(LParameter *lir); michael@0: bool visitCallee(LCallee *lir); michael@0: bool visitStart(LStart *lir); michael@0: bool visitReturn(LReturn *ret); michael@0: bool visitDefVar(LDefVar *lir); michael@0: bool visitDefFun(LDefFun *lir); michael@0: bool visitOsrEntry(LOsrEntry *lir); michael@0: bool visitOsrScopeChain(LOsrScopeChain *lir); michael@0: bool visitOsrValue(LOsrValue *lir); michael@0: bool visitOsrReturnValue(LOsrReturnValue *lir); michael@0: bool visitOsrArgumentsObject(LOsrArgumentsObject *lir); michael@0: bool visitStackArgT(LStackArgT *lir); michael@0: bool visitStackArgV(LStackArgV *lir); michael@0: bool visitMoveGroup(LMoveGroup *group); michael@0: bool visitValueToInt32(LValueToInt32 *lir); michael@0: bool visitValueToDouble(LValueToDouble *lir); michael@0: bool visitValueToFloat32(LValueToFloat32 *lir); michael@0: bool visitFloat32ToDouble(LFloat32ToDouble *lir); michael@0: bool visitDoubleToFloat32(LDoubleToFloat32 *lir); michael@0: bool visitInt32ToFloat32(LInt32ToFloat32 *lir); michael@0: bool visitInt32ToDouble(LInt32ToDouble *lir); michael@0: void emitOOLTestObject(Register objreg, Label *ifTruthy, Label *ifFalsy, Register scratch); michael@0: bool visitTestOAndBranch(LTestOAndBranch *lir); michael@0: bool visitTestVAndBranch(LTestVAndBranch *lir); michael@0: bool visitFunctionDispatch(LFunctionDispatch *lir); michael@0: bool visitTypeObjectDispatch(LTypeObjectDispatch *lir); michael@0: bool visitBooleanToString(LBooleanToString *lir); michael@0: void emitIntToString(Register input, Register output, Label *ool); michael@0: bool visitIntToString(LIntToString *lir); michael@0: bool visitDoubleToString(LDoubleToString *lir); michael@0: bool visitPrimitiveToString(LPrimitiveToString *lir); michael@0: bool visitInteger(LInteger *lir); michael@0: bool visitRegExp(LRegExp *lir); michael@0: bool visitRegExpExec(LRegExpExec *lir); michael@0: bool visitRegExpTest(LRegExpTest *lir); michael@0: bool visitRegExpReplace(LRegExpReplace *lir); michael@0: bool visitStringReplace(LStringReplace *lir); michael@0: bool visitLambda(LLambda *lir); michael@0: bool visitLambdaArrow(LLambdaArrow *lir); michael@0: bool visitLambdaForSingleton(LLambdaForSingleton *lir); michael@0: bool visitLambdaPar(LLambdaPar *lir); michael@0: bool visitPointer(LPointer *lir); michael@0: bool visitSlots(LSlots *lir); michael@0: bool visitStoreSlotV(LStoreSlotV *store); michael@0: bool visitElements(LElements *lir); michael@0: bool visitConvertElementsToDoubles(LConvertElementsToDoubles *lir); michael@0: bool visitMaybeToDoubleElement(LMaybeToDoubleElement *lir); michael@0: bool visitGuardObjectIdentity(LGuardObjectIdentity *guard); michael@0: bool visitTypeBarrierV(LTypeBarrierV *lir); michael@0: bool visitTypeBarrierO(LTypeBarrierO *lir); michael@0: bool visitMonitorTypes(LMonitorTypes *lir); michael@0: bool visitPostWriteBarrierO(LPostWriteBarrierO *lir); michael@0: bool visitPostWriteBarrierV(LPostWriteBarrierV *lir); michael@0: bool visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier *ool); michael@0: bool visitCallNative(LCallNative *call); michael@0: bool emitCallInvokeFunction(LInstruction *call, Register callereg, michael@0: uint32_t argc, uint32_t unusedStack); michael@0: bool visitCallGeneric(LCallGeneric *call); michael@0: bool visitCallKnown(LCallKnown *call); michael@0: bool emitCallInvokeFunction(LApplyArgsGeneric *apply, Register extraStackSize); michael@0: void emitPushArguments(LApplyArgsGeneric *apply, Register extraStackSpace); michael@0: void emitPopArguments(LApplyArgsGeneric *apply, Register extraStackSize); michael@0: bool visitApplyArgsGeneric(LApplyArgsGeneric *apply); michael@0: bool visitBail(LBail *lir); michael@0: bool visitGetDynamicName(LGetDynamicName *lir); michael@0: bool visitFilterArgumentsOrEvalS(LFilterArgumentsOrEvalS *lir); michael@0: bool visitFilterArgumentsOrEvalV(LFilterArgumentsOrEvalV *lir); michael@0: bool visitCallDirectEvalS(LCallDirectEvalS *lir); michael@0: bool visitCallDirectEvalV(LCallDirectEvalV *lir); michael@0: bool visitDoubleToInt32(LDoubleToInt32 *lir); michael@0: bool visitFloat32ToInt32(LFloat32ToInt32 *lir); michael@0: bool visitNewSlots(LNewSlots *lir); michael@0: bool visitNewArrayCallVM(LNewArray *lir); michael@0: bool visitNewArray(LNewArray *lir); michael@0: bool visitOutOfLineNewArray(OutOfLineNewArray *ool); michael@0: bool visitNewObjectVMCall(LNewObject *lir); michael@0: bool visitNewObject(LNewObject *lir); michael@0: bool visitOutOfLineNewObject(OutOfLineNewObject *ool); michael@0: bool visitNewDeclEnvObject(LNewDeclEnvObject *lir); michael@0: bool visitNewCallObject(LNewCallObject *lir); michael@0: bool visitNewSingletonCallObject(LNewSingletonCallObject *lir); michael@0: bool visitNewCallObjectPar(LNewCallObjectPar *lir); michael@0: bool visitNewStringObject(LNewStringObject *lir); michael@0: bool visitNewPar(LNewPar *lir); michael@0: bool visitNewDenseArrayPar(LNewDenseArrayPar *lir); michael@0: bool visitNewDerivedTypedObject(LNewDerivedTypedObject *lir); michael@0: bool visitAbortPar(LAbortPar *lir); michael@0: bool visitInitElem(LInitElem *lir); michael@0: bool visitInitElemGetterSetter(LInitElemGetterSetter *lir); michael@0: bool visitMutateProto(LMutateProto *lir); michael@0: bool visitInitProp(LInitProp *lir); michael@0: bool visitInitPropGetterSetter(LInitPropGetterSetter *lir); michael@0: bool visitCreateThis(LCreateThis *lir); michael@0: bool visitCreateThisWithProto(LCreateThisWithProto *lir); michael@0: bool visitCreateThisWithTemplate(LCreateThisWithTemplate *lir); michael@0: bool visitCreateArgumentsObject(LCreateArgumentsObject *lir); michael@0: bool visitGetArgumentsObjectArg(LGetArgumentsObjectArg *lir); michael@0: bool visitSetArgumentsObjectArg(LSetArgumentsObjectArg *lir); michael@0: bool visitReturnFromCtor(LReturnFromCtor *lir); michael@0: bool visitComputeThis(LComputeThis *lir); michael@0: bool visitLoadArrowThis(LLoadArrowThis *lir); michael@0: bool visitArrayLength(LArrayLength *lir); michael@0: bool visitSetArrayLength(LSetArrayLength *lir); michael@0: bool visitTypedArrayLength(LTypedArrayLength *lir); michael@0: bool visitTypedArrayElements(LTypedArrayElements *lir); michael@0: bool visitNeuterCheck(LNeuterCheck *lir); michael@0: bool visitTypedObjectElements(LTypedObjectElements *lir); michael@0: bool visitSetTypedObjectOffset(LSetTypedObjectOffset *lir); michael@0: bool visitStringLength(LStringLength *lir); michael@0: bool visitInitializedLength(LInitializedLength *lir); michael@0: bool visitSetInitializedLength(LSetInitializedLength *lir); michael@0: bool visitNotO(LNotO *ins); michael@0: bool visitNotV(LNotV *ins); michael@0: bool visitBoundsCheck(LBoundsCheck *lir); michael@0: bool visitBoundsCheckRange(LBoundsCheckRange *lir); michael@0: bool visitBoundsCheckLower(LBoundsCheckLower *lir); michael@0: bool visitLoadFixedSlotV(LLoadFixedSlotV *ins); michael@0: bool visitLoadFixedSlotT(LLoadFixedSlotT *ins); michael@0: bool visitStoreFixedSlotV(LStoreFixedSlotV *ins); michael@0: bool visitStoreFixedSlotT(LStoreFixedSlotT *ins); michael@0: bool emitGetPropertyPolymorphic(LInstruction *lir, Register obj, michael@0: Register scratch, const TypedOrValueRegister &output); michael@0: bool visitGetPropertyPolymorphicV(LGetPropertyPolymorphicV *ins); michael@0: bool visitGetPropertyPolymorphicT(LGetPropertyPolymorphicT *ins); michael@0: bool emitSetPropertyPolymorphic(LInstruction *lir, Register obj, michael@0: Register scratch, const ConstantOrRegister &value); michael@0: bool visitSetPropertyPolymorphicV(LSetPropertyPolymorphicV *ins); michael@0: bool visitArraySplice(LArraySplice *splice); michael@0: bool visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT *ins); michael@0: bool visitAbsI(LAbsI *lir); michael@0: bool visitAtan2D(LAtan2D *lir); michael@0: bool visitHypot(LHypot *lir); michael@0: bool visitPowI(LPowI *lir); michael@0: bool visitPowD(LPowD *lir); michael@0: bool visitRandom(LRandom *lir); michael@0: bool visitMathFunctionD(LMathFunctionD *ins); michael@0: bool visitMathFunctionF(LMathFunctionF *ins); michael@0: bool visitModD(LModD *ins); michael@0: bool visitMinMaxI(LMinMaxI *lir); michael@0: bool visitBinaryV(LBinaryV *lir); michael@0: bool emitCompareS(LInstruction *lir, JSOp op, Register left, Register right, michael@0: Register output, Register temp); michael@0: bool visitCompareS(LCompareS *lir); michael@0: bool visitCompareStrictS(LCompareStrictS *lir); michael@0: bool visitCompareVM(LCompareVM *lir); michael@0: bool visitIsNullOrLikeUndefined(LIsNullOrLikeUndefined *lir); michael@0: bool visitIsNullOrLikeUndefinedAndBranch(LIsNullOrLikeUndefinedAndBranch *lir); michael@0: bool visitEmulatesUndefined(LEmulatesUndefined *lir); michael@0: bool visitEmulatesUndefinedAndBranch(LEmulatesUndefinedAndBranch *lir); michael@0: bool emitConcat(LInstruction *lir, Register lhs, Register rhs, Register output); michael@0: bool visitConcat(LConcat *lir); michael@0: bool visitConcatPar(LConcatPar *lir); michael@0: bool visitCharCodeAt(LCharCodeAt *lir); michael@0: bool visitFromCharCode(LFromCharCode *lir); michael@0: bool visitStringSplit(LStringSplit *lir); michael@0: bool visitFunctionEnvironment(LFunctionEnvironment *lir); michael@0: bool visitForkJoinContext(LForkJoinContext *lir); michael@0: bool visitGuardThreadExclusive(LGuardThreadExclusive *lir); michael@0: bool visitCallGetProperty(LCallGetProperty *lir); michael@0: bool visitCallGetElement(LCallGetElement *lir); michael@0: bool visitCallSetElement(LCallSetElement *lir); michael@0: bool visitCallInitElementArray(LCallInitElementArray *lir); michael@0: bool visitThrow(LThrow *lir); michael@0: bool visitTypeOfV(LTypeOfV *lir); michael@0: bool visitOutOfLineTypeOfV(OutOfLineTypeOfV *ool); michael@0: bool visitToIdV(LToIdV *lir); michael@0: bool visitLoadElementV(LLoadElementV *load); michael@0: bool visitLoadElementHole(LLoadElementHole *lir); michael@0: bool visitStoreElementT(LStoreElementT *lir); michael@0: bool visitStoreElementV(LStoreElementV *lir); michael@0: bool visitStoreElementHoleT(LStoreElementHoleT *lir); michael@0: bool visitStoreElementHoleV(LStoreElementHoleV *lir); michael@0: bool emitArrayPopShift(LInstruction *lir, const MArrayPopShift *mir, Register obj, michael@0: Register elementsTemp, Register lengthTemp, TypedOrValueRegister out); michael@0: bool visitArrayPopShiftV(LArrayPopShiftV *lir); michael@0: bool visitArrayPopShiftT(LArrayPopShiftT *lir); michael@0: bool emitArrayPush(LInstruction *lir, const MArrayPush *mir, Register obj, michael@0: ConstantOrRegister value, Register elementsTemp, Register length); michael@0: bool visitArrayPushV(LArrayPushV *lir); michael@0: bool visitArrayPushT(LArrayPushT *lir); michael@0: bool visitArrayConcat(LArrayConcat *lir); michael@0: bool visitLoadTypedArrayElement(LLoadTypedArrayElement *lir); michael@0: bool visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole *lir); michael@0: bool visitStoreTypedArrayElement(LStoreTypedArrayElement *lir); michael@0: bool visitStoreTypedArrayElementHole(LStoreTypedArrayElementHole *lir); michael@0: bool visitClampIToUint8(LClampIToUint8 *lir); michael@0: bool visitClampDToUint8(LClampDToUint8 *lir); michael@0: bool visitClampVToUint8(LClampVToUint8 *lir); michael@0: bool visitCallIteratorStart(LCallIteratorStart *lir); michael@0: bool visitIteratorStart(LIteratorStart *lir); michael@0: bool visitIteratorNext(LIteratorNext *lir); michael@0: bool visitIteratorMore(LIteratorMore *lir); michael@0: bool visitIteratorEnd(LIteratorEnd *lir); michael@0: bool visitArgumentsLength(LArgumentsLength *lir); michael@0: bool visitGetFrameArgument(LGetFrameArgument *lir); michael@0: bool visitSetFrameArgumentT(LSetFrameArgumentT *lir); michael@0: bool visitSetFrameArgumentC(LSetFrameArgumentC *lir); michael@0: bool visitSetFrameArgumentV(LSetFrameArgumentV *lir); michael@0: bool visitRunOncePrologue(LRunOncePrologue *lir); michael@0: bool emitRest(LInstruction *lir, Register array, Register numActuals, michael@0: Register temp0, Register temp1, unsigned numFormals, michael@0: JSObject *templateObject); michael@0: bool visitRest(LRest *lir); michael@0: bool visitRestPar(LRestPar *lir); michael@0: bool visitCallSetProperty(LCallSetProperty *ins); michael@0: bool visitCallDeleteProperty(LCallDeleteProperty *lir); michael@0: bool visitCallDeleteElement(LCallDeleteElement *lir); michael@0: bool visitBitNotV(LBitNotV *lir); michael@0: bool visitBitOpV(LBitOpV *lir); michael@0: bool emitInstanceOf(LInstruction *ins, JSObject *prototypeObject); michael@0: bool visitIn(LIn *ins); michael@0: bool visitInArray(LInArray *ins); michael@0: bool visitInstanceOfO(LInstanceOfO *ins); michael@0: bool visitInstanceOfV(LInstanceOfV *ins); michael@0: bool visitCallInstanceOf(LCallInstanceOf *ins); michael@0: bool visitProfilerStackOp(LProfilerStackOp *lir); michael@0: bool visitGetDOMProperty(LGetDOMProperty *lir); michael@0: bool visitGetDOMMember(LGetDOMMember *lir); michael@0: bool visitSetDOMProperty(LSetDOMProperty *lir); michael@0: bool visitCallDOMNative(LCallDOMNative *lir); michael@0: bool visitCallGetIntrinsicValue(LCallGetIntrinsicValue *lir); michael@0: bool visitIsCallable(LIsCallable *lir); michael@0: bool visitHaveSameClass(LHaveSameClass *lir); michael@0: bool visitHasClass(LHasClass *lir); michael@0: bool visitAsmJSCall(LAsmJSCall *lir); michael@0: bool visitAsmJSParameter(LAsmJSParameter *lir); michael@0: bool visitAsmJSReturn(LAsmJSReturn *ret); michael@0: bool visitAsmJSVoidReturn(LAsmJSVoidReturn *ret); michael@0: michael@0: bool visitCheckOverRecursed(LCheckOverRecursed *lir); michael@0: bool visitCheckOverRecursedFailure(CheckOverRecursedFailure *ool); michael@0: michael@0: bool visitCheckOverRecursedPar(LCheckOverRecursedPar *lir); michael@0: bool visitCheckOverRecursedFailurePar(CheckOverRecursedFailurePar *ool); michael@0: michael@0: bool visitInterruptCheckPar(LInterruptCheckPar *lir); michael@0: bool visitOutOfLineInterruptCheckPar(OutOfLineInterruptCheckPar *ool); michael@0: michael@0: bool visitInterruptCheckImplicit(LInterruptCheckImplicit *ins); michael@0: bool visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit *ins); michael@0: michael@0: bool visitUnboxFloatingPoint(LUnboxFloatingPoint *lir); michael@0: bool visitOutOfLineUnboxFloatingPoint(OutOfLineUnboxFloatingPoint *ool); michael@0: bool visitOutOfLineStoreElementHole(OutOfLineStoreElementHole *ool); michael@0: michael@0: bool visitOutOfLineNewGCThingPar(OutOfLineNewGCThingPar *ool); michael@0: bool visitOutOfLineAbortPar(OutOfLineAbortPar *ool); michael@0: bool visitOutOfLinePropagateAbortPar(OutOfLinePropagateAbortPar *ool); michael@0: void loadJSScriptForBlock(MBasicBlock *block, Register reg); michael@0: void loadOutermostJSScript(Register reg); michael@0: michael@0: // Inline caches visitors. michael@0: bool visitOutOfLineCache(OutOfLineUpdateCache *ool); michael@0: michael@0: bool visitGetPropertyCacheV(LGetPropertyCacheV *ins); michael@0: bool visitGetPropertyCacheT(LGetPropertyCacheT *ins); michael@0: bool visitGetElementCacheV(LGetElementCacheV *ins); michael@0: bool visitGetElementCacheT(LGetElementCacheT *ins); michael@0: bool visitSetElementCacheV(LSetElementCacheV *ins); michael@0: bool visitSetElementCacheT(LSetElementCacheT *ins); michael@0: bool visitBindNameCache(LBindNameCache *ins); michael@0: bool visitCallSetProperty(LInstruction *ins); michael@0: bool visitSetPropertyCacheV(LSetPropertyCacheV *ins); michael@0: bool visitSetPropertyCacheT(LSetPropertyCacheT *ins); michael@0: bool visitGetNameCache(LGetNameCache *ins); michael@0: bool visitCallsiteCloneCache(LCallsiteCloneCache *ins); michael@0: michael@0: bool visitGetPropertyIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitGetPropertyParIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitSetPropertyIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitSetPropertyParIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitGetElementIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitGetElementParIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitSetElementIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitSetElementParIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitBindNameIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitNameIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: bool visitCallsiteCloneIC(OutOfLineUpdateCache *ool, DataPtr &ic); michael@0: michael@0: bool visitAssertRangeI(LAssertRangeI *ins); michael@0: bool visitAssertRangeD(LAssertRangeD *ins); michael@0: bool visitAssertRangeF(LAssertRangeF *ins); michael@0: bool visitAssertRangeV(LAssertRangeV *ins); michael@0: michael@0: bool visitRecompileCheck(LRecompileCheck *ins); michael@0: michael@0: private: michael@0: bool addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg, michael@0: PropertyName *name, TypedOrValueRegister output, michael@0: bool monitoredResult); michael@0: bool addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index, michael@0: TypedOrValueRegister output, bool monitoredResult, michael@0: bool allowDoubleResult); michael@0: bool addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg, michael@0: PropertyName *name, ConstantOrRegister value, bool strict, michael@0: bool needsTypeBarrier); michael@0: bool addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex, Register temp, michael@0: FloatRegister tempFloat, ValueOperand index, ConstantOrRegister value, michael@0: bool strict, bool guardHoles); michael@0: bool checkForAbortPar(LInstruction *lir); michael@0: michael@0: bool generateBranchV(const ValueOperand &value, Label *ifTrue, Label *ifFalse, FloatRegister fr); michael@0: michael@0: bool emitAllocateGCThingPar(LInstruction *lir, Register objReg, Register cxReg, michael@0: Register tempReg1, Register tempReg2, michael@0: JSObject *templateObj); michael@0: michael@0: bool emitCallToUncompiledScriptPar(LInstruction *lir, Register calleeReg); michael@0: michael@0: void emitLambdaInit(Register resultReg, Register scopeChainReg, michael@0: const LambdaFunctionInfo &info); michael@0: michael@0: bool emitFilterArgumentsOrEval(LInstruction *lir, Register string, Register temp1, michael@0: Register temp2); michael@0: michael@0: IonScriptCounts *maybeCreateScriptCounts(); michael@0: michael@0: // This function behaves like testValueTruthy with the exception that it can michael@0: // choose to let control flow fall through when the object is truthy, as michael@0: // an optimization. Use testValueTruthy when it's required to branch to one michael@0: // of the two labels. michael@0: void testValueTruthyKernel(const ValueOperand &value, michael@0: const LDefinition *scratch1, const LDefinition *scratch2, michael@0: FloatRegister fr, michael@0: Label *ifTruthy, Label *ifFalsy, michael@0: OutOfLineTestObject *ool); michael@0: michael@0: // Test whether value is truthy or not and jump to the corresponding label. michael@0: // If the value can be an object that emulates |undefined|, |ool| must be michael@0: // non-null; otherwise it may be null (and the scratch definitions should michael@0: // be bogus), in which case an object encountered here will always be michael@0: // truthy. michael@0: void testValueTruthy(const ValueOperand &value, michael@0: const LDefinition *scratch1, const LDefinition *scratch2, michael@0: FloatRegister fr, michael@0: Label *ifTruthy, Label *ifFalsy, michael@0: OutOfLineTestObject *ool); michael@0: michael@0: // This function behaves like testObjectEmulatesUndefined with the exception michael@0: // that it can choose to let control flow fall through when the object michael@0: // doesn't emulate undefined, as an optimization. Use the regular michael@0: // testObjectEmulatesUndefined when it's required to branch to one of the michael@0: // two labels. michael@0: void testObjectEmulatesUndefinedKernel(Register objreg, michael@0: Label *ifEmulatesUndefined, michael@0: Label *ifDoesntEmulateUndefined, michael@0: Register scratch, OutOfLineTestObject *ool); michael@0: michael@0: // Test whether an object emulates |undefined|. If it does, jump to michael@0: // |ifEmulatesUndefined|; the caller is responsible for binding this label. michael@0: // If it doesn't, fall through; the label |ifDoesntEmulateUndefined| (which michael@0: // must be initially unbound) will be bound at this point. michael@0: void branchTestObjectEmulatesUndefined(Register objreg, michael@0: Label *ifEmulatesUndefined, michael@0: Label *ifDoesntEmulateUndefined, michael@0: Register scratch, OutOfLineTestObject *ool); michael@0: michael@0: // Test whether an object emulates |undefined|, and jump to the michael@0: // corresponding label. michael@0: // michael@0: // This method should be used when subsequent code can't be laid out in a michael@0: // straight line; if it can, branchTest* should be used instead. michael@0: void testObjectEmulatesUndefined(Register objreg, michael@0: Label *ifEmulatesUndefined, michael@0: Label *ifDoesntEmulateUndefined, michael@0: Register scratch, OutOfLineTestObject *ool); michael@0: michael@0: // Get a label for the start of block which can be used for jumping, in michael@0: // place of jumpToBlock. michael@0: Label *getJumpLabelForBranch(MBasicBlock *block); michael@0: michael@0: // Bailout if an element about to be written to is a hole. michael@0: bool emitStoreHoleCheck(Register elements, const LAllocation *index, LSnapshot *snapshot); michael@0: michael@0: bool emitAssertRangeI(const Range *r, Register input); michael@0: bool emitAssertRangeD(const Range *r, FloatRegister input, FloatRegister temp); michael@0: michael@0: Vector ionScriptLabels_; michael@0: #ifdef DEBUG michael@0: bool branchIfInvalidated(Register temp, Label *invalidated); michael@0: michael@0: bool emitDebugResultChecks(LInstruction *ins); michael@0: bool emitObjectOrStringResultChecks(LInstruction *lir, MDefinition *mir); michael@0: bool emitValueResultChecks(LInstruction *lir, MDefinition *mir); michael@0: #endif michael@0: michael@0: #if defined(JS_ION_PERF) michael@0: PerfSpewer perfSpewer_; michael@0: #endif michael@0: }; michael@0: michael@0: } // namespace jit michael@0: } // namespace js michael@0: michael@0: #endif /* jit_CodeGenerator_h */