summaryrefslogtreecommitdiffstats
path: root/js/src/jit/CodeGenerator.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/CodeGenerator.h')
-rw-r--r--js/src/jit/CodeGenerator.h593
1 files changed, 593 insertions, 0 deletions
diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h
new file mode 100644
index 000000000..8f4bcc813
--- /dev/null
+++ b/js/src/jit/CodeGenerator.h
@@ -0,0 +1,593 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef jit_CodeGenerator_h
+#define jit_CodeGenerator_h
+
+#include "jit/IonCaches.h"
+#if defined(JS_ION_PERF)
+# include "jit/PerfSpewer.h"
+#endif
+
+#if defined(JS_CODEGEN_X86)
+# include "jit/x86/CodeGenerator-x86.h"
+#elif defined(JS_CODEGEN_X64)
+# include "jit/x64/CodeGenerator-x64.h"
+#elif defined(JS_CODEGEN_ARM)
+# include "jit/arm/CodeGenerator-arm.h"
+#elif defined(JS_CODEGEN_ARM64)
+# include "jit/arm64/CodeGenerator-arm64.h"
+#elif defined(JS_CODEGEN_MIPS32)
+# include "jit/mips32/CodeGenerator-mips32.h"
+#elif defined(JS_CODEGEN_MIPS64)
+# include "jit/mips64/CodeGenerator-mips64.h"
+#elif defined(JS_CODEGEN_NONE)
+# include "jit/none/CodeGenerator-none.h"
+#else
+#error "Unknown architecture!"
+#endif
+
+namespace js {
+namespace jit {
+
+class OutOfLineTestObject;
+class OutOfLineNewArray;
+class OutOfLineNewObject;
+class CheckOverRecursedFailure;
+class OutOfLineInterruptCheckImplicit;
+class OutOfLineUnboxFloatingPoint;
+class OutOfLineStoreElementHole;
+class OutOfLineTypeOfV;
+class OutOfLineUpdateCache;
+class OutOfLineCallPostWriteBarrier;
+class OutOfLineCallPostWriteElementBarrier;
+class OutOfLineIsCallable;
+class OutOfLineIsConstructor;
+class OutOfLineRegExpMatcher;
+class OutOfLineRegExpSearcher;
+class OutOfLineRegExpTester;
+class OutOfLineRegExpPrototypeOptimizable;
+class OutOfLineRegExpInstanceOptimizable;
+class OutOfLineLambdaArrow;
+class OutOfLineNaNToZero;
+
+class CodeGenerator final : public CodeGeneratorSpecific
+{
+ void generateArgumentsChecks(bool bailout = true);
+ MOZ_MUST_USE bool generateBody();
+
+ ConstantOrRegister toConstantOrRegister(LInstruction* lir, size_t n, MIRType type);
+
+ public:
+ CodeGenerator(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm = nullptr);
+ ~CodeGenerator();
+
+ public:
+ MOZ_MUST_USE bool generate();
+ MOZ_MUST_USE bool generateWasm(wasm::SigIdDesc sigId, wasm::TrapOffset trapOffset,
+ wasm::FuncOffsets *offsets);
+ MOZ_MUST_USE bool link(JSContext* cx, CompilerConstraintList* constraints);
+ MOZ_MUST_USE bool linkSharedStubs(JSContext* cx);
+
+ void visitOsiPoint(LOsiPoint* lir);
+ void visitGoto(LGoto* lir);
+ void visitTableSwitch(LTableSwitch* ins);
+ void visitTableSwitchV(LTableSwitchV* ins);
+ void visitCloneLiteral(LCloneLiteral* lir);
+ void visitParameter(LParameter* lir);
+ void visitCallee(LCallee* lir);
+ void visitIsConstructing(LIsConstructing* lir);
+ void visitStart(LStart* lir);
+ void visitReturn(LReturn* ret);
+ void visitDefVar(LDefVar* lir);
+ void visitDefLexical(LDefLexical* lir);
+ void visitDefFun(LDefFun* lir);
+ void visitOsrEntry(LOsrEntry* lir);
+ void visitOsrEnvironmentChain(LOsrEnvironmentChain* lir);
+ void visitOsrValue(LOsrValue* lir);
+ void visitOsrReturnValue(LOsrReturnValue* lir);
+ void visitOsrArgumentsObject(LOsrArgumentsObject* lir);
+ void visitStackArgT(LStackArgT* lir);
+ void visitStackArgV(LStackArgV* lir);
+ void visitMoveGroup(LMoveGroup* group);
+ void visitValueToInt32(LValueToInt32* lir);
+ void visitValueToDouble(LValueToDouble* lir);
+ void visitValueToFloat32(LValueToFloat32* lir);
+ void visitFloat32ToDouble(LFloat32ToDouble* lir);
+ void visitDoubleToFloat32(LDoubleToFloat32* lir);
+ void visitInt32ToFloat32(LInt32ToFloat32* lir);
+ void visitInt32ToDouble(LInt32ToDouble* lir);
+ void emitOOLTestObject(Register objreg, Label* ifTruthy, Label* ifFalsy, Register scratch);
+ void visitTestOAndBranch(LTestOAndBranch* lir);
+ void visitTestVAndBranch(LTestVAndBranch* lir);
+ void visitFunctionDispatch(LFunctionDispatch* lir);
+ void visitObjectGroupDispatch(LObjectGroupDispatch* lir);
+ void visitBooleanToString(LBooleanToString* lir);
+ void emitIntToString(Register input, Register output, Label* ool);
+ void visitIntToString(LIntToString* lir);
+ void visitDoubleToString(LDoubleToString* lir);
+ void visitValueToString(LValueToString* lir);
+ void visitValueToObjectOrNull(LValueToObjectOrNull* lir);
+ void visitInteger(LInteger* lir);
+ void visitInteger64(LInteger64* lir);
+ void visitRegExp(LRegExp* lir);
+ void visitRegExpMatcher(LRegExpMatcher* lir);
+ void visitOutOfLineRegExpMatcher(OutOfLineRegExpMatcher* ool);
+ void visitRegExpSearcher(LRegExpSearcher* lir);
+ void visitOutOfLineRegExpSearcher(OutOfLineRegExpSearcher* ool);
+ void visitRegExpTester(LRegExpTester* lir);
+ void visitOutOfLineRegExpTester(OutOfLineRegExpTester* ool);
+ void visitRegExpPrototypeOptimizable(LRegExpPrototypeOptimizable* lir);
+ void visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototypeOptimizable* ool);
+ void visitRegExpInstanceOptimizable(LRegExpInstanceOptimizable* lir);
+ void visitOutOfLineRegExpInstanceOptimizable(OutOfLineRegExpInstanceOptimizable* ool);
+ void visitGetFirstDollarIndex(LGetFirstDollarIndex* lir);
+ void visitStringReplace(LStringReplace* lir);
+ void emitSharedStub(ICStub::Kind kind, LInstruction* lir);
+ void visitBinarySharedStub(LBinarySharedStub* lir);
+ void visitUnarySharedStub(LUnarySharedStub* lir);
+ void visitNullarySharedStub(LNullarySharedStub* lir);
+ void visitLambda(LLambda* lir);
+ void visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool);
+ void visitLambdaArrow(LLambdaArrow* lir);
+ void visitLambdaForSingleton(LLambdaForSingleton* lir);
+ void visitPointer(LPointer* lir);
+ void visitKeepAliveObject(LKeepAliveObject* lir);
+ void visitSlots(LSlots* lir);
+ void visitLoadSlotT(LLoadSlotT* lir);
+ void visitLoadSlotV(LLoadSlotV* lir);
+ void visitStoreSlotT(LStoreSlotT* lir);
+ void visitStoreSlotV(LStoreSlotV* lir);
+ void visitElements(LElements* lir);
+ void visitConvertElementsToDoubles(LConvertElementsToDoubles* lir);
+ void visitMaybeToDoubleElement(LMaybeToDoubleElement* lir);
+ void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir);
+ void visitGuardObjectIdentity(LGuardObjectIdentity* guard);
+ void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir);
+ void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir);
+ void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir);
+ void visitTypeBarrierV(LTypeBarrierV* lir);
+ void visitTypeBarrierO(LTypeBarrierO* lir);
+ void visitMonitorTypes(LMonitorTypes* lir);
+ void emitPostWriteBarrier(const LAllocation* obj);
+ void emitPostWriteBarrier(Register objreg);
+ template <class LPostBarrierType>
+ void visitPostWriteBarrierCommonO(LPostBarrierType* lir, OutOfLineCode* ool);
+ template <class LPostBarrierType>
+ void visitPostWriteBarrierCommonV(LPostBarrierType* lir, OutOfLineCode* ool);
+ void visitPostWriteBarrierO(LPostWriteBarrierO* lir);
+ void visitPostWriteElementBarrierO(LPostWriteElementBarrierO* lir);
+ void visitPostWriteBarrierV(LPostWriteBarrierV* lir);
+ void visitPostWriteElementBarrierV(LPostWriteElementBarrierV* lir);
+ void visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier* ool);
+ void visitOutOfLineCallPostWriteElementBarrier(OutOfLineCallPostWriteElementBarrier* ool);
+ void visitCallNative(LCallNative* call);
+ void emitCallInvokeFunction(LInstruction* call, Register callereg,
+ bool isConstructing, uint32_t argc,
+ uint32_t unusedStack);
+ void visitCallGeneric(LCallGeneric* call);
+ void emitCallInvokeFunctionShuffleNewTarget(LCallKnown *call,
+ Register calleeReg,
+ uint32_t numFormals,
+ uint32_t unusedStack);
+ void visitCallKnown(LCallKnown* call);
+ template<typename T> void emitApplyGeneric(T* apply);
+ template<typename T> void emitCallInvokeFunction(T* apply, Register extraStackSize);
+ void emitAllocateSpaceForApply(Register argcreg, Register extraStackSpace, Label* end);
+ void emitCopyValuesForApply(Register argvSrcBase, Register argvIndex, Register copyreg,
+ size_t argvSrcOffset, size_t argvDstOffset);
+ void emitPopArguments(Register extraStackSize);
+ void emitPushArguments(LApplyArgsGeneric* apply, Register extraStackSpace);
+ void visitApplyArgsGeneric(LApplyArgsGeneric* apply);
+ void emitPushArguments(LApplyArrayGeneric* apply, Register extraStackSpace);
+ void visitApplyArrayGeneric(LApplyArrayGeneric* apply);
+ void visitBail(LBail* lir);
+ void visitUnreachable(LUnreachable* unreachable);
+ void visitEncodeSnapshot(LEncodeSnapshot* lir);
+ void visitGetDynamicName(LGetDynamicName* lir);
+ void visitCallDirectEval(LCallDirectEval* lir);
+ void visitDoubleToInt32(LDoubleToInt32* lir);
+ void visitFloat32ToInt32(LFloat32ToInt32* lir);
+ void visitNewArrayCallVM(LNewArray* lir);
+ void visitNewArray(LNewArray* lir);
+ void visitOutOfLineNewArray(OutOfLineNewArray* ool);
+ void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir);
+ void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir);
+ void visitNewTypedArray(LNewTypedArray* lir);
+ void visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir);
+ void visitNewObjectVMCall(LNewObject* lir);
+ void visitNewObject(LNewObject* lir);
+ void visitOutOfLineNewObject(OutOfLineNewObject* ool);
+ void visitNewTypedObject(LNewTypedObject* lir);
+ void visitSimdBox(LSimdBox* lir);
+ void visitSimdUnbox(LSimdUnbox* lir);
+ void visitNewNamedLambdaObject(LNewNamedLambdaObject* lir);
+ void visitNewCallObject(LNewCallObject* lir);
+ void visitNewSingletonCallObject(LNewSingletonCallObject* lir);
+ void visitNewStringObject(LNewStringObject* lir);
+ void visitNewDerivedTypedObject(LNewDerivedTypedObject* lir);
+ void visitInitElem(LInitElem* lir);
+ void visitInitElemGetterSetter(LInitElemGetterSetter* lir);
+ void visitMutateProto(LMutateProto* lir);
+ void visitInitProp(LInitProp* lir);
+ void visitInitPropGetterSetter(LInitPropGetterSetter* lir);
+ void visitCreateThis(LCreateThis* lir);
+ void visitCreateThisWithProto(LCreateThisWithProto* lir);
+ void visitCreateThisWithTemplate(LCreateThisWithTemplate* lir);
+ void visitCreateArgumentsObject(LCreateArgumentsObject* lir);
+ void visitGetArgumentsObjectArg(LGetArgumentsObjectArg* lir);
+ void visitSetArgumentsObjectArg(LSetArgumentsObjectArg* lir);
+ void visitReturnFromCtor(LReturnFromCtor* lir);
+ void visitComputeThis(LComputeThis* lir);
+ void visitArrayLength(LArrayLength* lir);
+ void visitSetArrayLength(LSetArrayLength* lir);
+ void visitGetNextEntryForIterator(LGetNextEntryForIterator* lir);
+ void visitTypedArrayLength(LTypedArrayLength* lir);
+ void visitTypedArrayElements(LTypedArrayElements* lir);
+ void visitSetDisjointTypedElements(LSetDisjointTypedElements* lir);
+ void visitTypedObjectElements(LTypedObjectElements* lir);
+ void visitSetTypedObjectOffset(LSetTypedObjectOffset* lir);
+ void visitTypedObjectDescr(LTypedObjectDescr* ins);
+ void visitStringLength(LStringLength* lir);
+ void visitSubstr(LSubstr* lir);
+ void visitInitializedLength(LInitializedLength* lir);
+ void visitSetInitializedLength(LSetInitializedLength* lir);
+ void visitUnboxedArrayLength(LUnboxedArrayLength* lir);
+ void visitUnboxedArrayInitializedLength(LUnboxedArrayInitializedLength* lir);
+ void visitIncrementUnboxedArrayInitializedLength(LIncrementUnboxedArrayInitializedLength* lir);
+ void visitSetUnboxedArrayInitializedLength(LSetUnboxedArrayInitializedLength* lir);
+ void visitNotO(LNotO* ins);
+ void visitNotV(LNotV* ins);
+ void visitBoundsCheck(LBoundsCheck* lir);
+ void visitBoundsCheckRange(LBoundsCheckRange* lir);
+ void visitBoundsCheckLower(LBoundsCheckLower* lir);
+ void visitLoadFixedSlotV(LLoadFixedSlotV* ins);
+ void visitLoadFixedSlotAndUnbox(LLoadFixedSlotAndUnbox* lir);
+ void visitLoadFixedSlotT(LLoadFixedSlotT* ins);
+ void visitStoreFixedSlotV(LStoreFixedSlotV* ins);
+ void visitStoreFixedSlotT(LStoreFixedSlotT* ins);
+ void emitGetPropertyPolymorphic(LInstruction* lir, Register obj,
+ Register scratch, const TypedOrValueRegister& output);
+ void visitGetPropertyPolymorphicV(LGetPropertyPolymorphicV* ins);
+ void visitGetPropertyPolymorphicT(LGetPropertyPolymorphicT* ins);
+ void emitSetPropertyPolymorphic(LInstruction* lir, Register obj,
+ Register scratch, const ConstantOrRegister& value);
+ void visitSetPropertyPolymorphicV(LSetPropertyPolymorphicV* ins);
+ void visitArraySplice(LArraySplice* splice);
+ void visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins);
+ void visitAbsI(LAbsI* lir);
+ void visitAtan2D(LAtan2D* lir);
+ void visitHypot(LHypot* lir);
+ void visitPowI(LPowI* lir);
+ void visitPowD(LPowD* lir);
+ void visitMathFunctionD(LMathFunctionD* ins);
+ void visitMathFunctionF(LMathFunctionF* ins);
+ void visitModD(LModD* ins);
+ void visitMinMaxI(LMinMaxI* lir);
+ void visitBinaryV(LBinaryV* lir);
+ void emitCompareS(LInstruction* lir, JSOp op, Register left, Register right, Register output);
+ void visitCompareS(LCompareS* lir);
+ void visitCompareStrictS(LCompareStrictS* lir);
+ void visitCompareVM(LCompareVM* lir);
+ void visitIsNullOrLikeUndefinedV(LIsNullOrLikeUndefinedV* lir);
+ void visitIsNullOrLikeUndefinedT(LIsNullOrLikeUndefinedT* lir);
+ void visitIsNullOrLikeUndefinedAndBranchV(LIsNullOrLikeUndefinedAndBranchV* lir);
+ void visitIsNullOrLikeUndefinedAndBranchT(LIsNullOrLikeUndefinedAndBranchT* lir);
+ void emitConcat(LInstruction* lir, Register lhs, Register rhs, Register output);
+ void visitConcat(LConcat* lir);
+ void visitCharCodeAt(LCharCodeAt* lir);
+ void visitFromCharCode(LFromCharCode* lir);
+ void visitFromCodePoint(LFromCodePoint* lir);
+ void visitSinCos(LSinCos *lir);
+ void visitStringSplit(LStringSplit* lir);
+ void visitFunctionEnvironment(LFunctionEnvironment* lir);
+ void visitCallGetProperty(LCallGetProperty* lir);
+ void visitCallGetElement(LCallGetElement* lir);
+ void visitCallSetElement(LCallSetElement* lir);
+ void visitCallInitElementArray(LCallInitElementArray* lir);
+ void visitThrow(LThrow* lir);
+ void visitTypeOfV(LTypeOfV* lir);
+ void visitOutOfLineTypeOfV(OutOfLineTypeOfV* ool);
+ void visitToAsync(LToAsync* lir);
+ void visitToIdV(LToIdV* lir);
+ template<typename T> void emitLoadElementT(LLoadElementT* lir, const T& source);
+ void visitLoadElementT(LLoadElementT* lir);
+ void visitLoadElementV(LLoadElementV* load);
+ void visitLoadElementHole(LLoadElementHole* lir);
+ void visitLoadUnboxedPointerV(LLoadUnboxedPointerV* lir);
+ void visitLoadUnboxedPointerT(LLoadUnboxedPointerT* lir);
+ void visitUnboxObjectOrNull(LUnboxObjectOrNull* lir);
+ void visitStoreElementT(LStoreElementT* lir);
+ void visitStoreElementV(LStoreElementV* lir);
+ template <typename T> void emitStoreElementHoleT(T* lir);
+ template <typename T> void emitStoreElementHoleV(T* lir);
+ void visitStoreElementHoleT(LStoreElementHoleT* lir);
+ void visitStoreElementHoleV(LStoreElementHoleV* lir);
+ void visitFallibleStoreElementV(LFallibleStoreElementV* lir);
+ void visitFallibleStoreElementT(LFallibleStoreElementT* lir);
+ void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir);
+ void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir);
+ void emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, Register obj,
+ Register elementsTemp, Register lengthTemp, TypedOrValueRegister out);
+ void visitArrayPopShiftV(LArrayPopShiftV* lir);
+ void visitArrayPopShiftT(LArrayPopShiftT* lir);
+ void emitArrayPush(LInstruction* lir, const MArrayPush* mir, Register obj,
+ const ConstantOrRegister& value, Register elementsTemp, Register length);
+ void visitArrayPushV(LArrayPushV* lir);
+ void visitArrayPushT(LArrayPushT* lir);
+ void visitArraySlice(LArraySlice* lir);
+ void visitArrayJoin(LArrayJoin* lir);
+ void visitLoadUnboxedScalar(LLoadUnboxedScalar* lir);
+ void visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir);
+ void visitStoreUnboxedScalar(LStoreUnboxedScalar* lir);
+ void visitStoreTypedArrayElementHole(LStoreTypedArrayElementHole* lir);
+ void visitAtomicIsLockFree(LAtomicIsLockFree* lir);
+ void visitGuardSharedTypedArray(LGuardSharedTypedArray* lir);
+ void visitClampIToUint8(LClampIToUint8* lir);
+ void visitClampDToUint8(LClampDToUint8* lir);
+ void visitClampVToUint8(LClampVToUint8* lir);
+ void visitCallIteratorStartV(LCallIteratorStartV* lir);
+ void visitCallIteratorStartO(LCallIteratorStartO* lir);
+ void visitIteratorStartO(LIteratorStartO* lir);
+ void visitIteratorMore(LIteratorMore* lir);
+ void visitIsNoIterAndBranch(LIsNoIterAndBranch* lir);
+ void visitIteratorEnd(LIteratorEnd* lir);
+ void visitArgumentsLength(LArgumentsLength* lir);
+ void visitGetFrameArgument(LGetFrameArgument* lir);
+ void visitSetFrameArgumentT(LSetFrameArgumentT* lir);
+ void visitSetFrameArgumentC(LSetFrameArgumentC* lir);
+ void visitSetFrameArgumentV(LSetFrameArgumentV* lir);
+ void visitRunOncePrologue(LRunOncePrologue* lir);
+ void emitRest(LInstruction* lir, Register array, Register numActuals,
+ Register temp0, Register temp1, unsigned numFormals,
+ JSObject* templateObject, bool saveAndRestore, Register resultreg);
+ void visitRest(LRest* lir);
+ void visitCallSetProperty(LCallSetProperty* ins);
+ void visitCallDeleteProperty(LCallDeleteProperty* lir);
+ void visitCallDeleteElement(LCallDeleteElement* lir);
+ void visitBitNotV(LBitNotV* lir);
+ void visitBitOpV(LBitOpV* lir);
+ void emitInstanceOf(LInstruction* ins, JSObject* prototypeObject);
+ void visitIn(LIn* ins);
+ void visitInArray(LInArray* ins);
+ void visitInstanceOfO(LInstanceOfO* ins);
+ void visitInstanceOfV(LInstanceOfV* ins);
+ void visitCallInstanceOf(LCallInstanceOf* ins);
+ void visitGetDOMProperty(LGetDOMProperty* lir);
+ void visitGetDOMMemberV(LGetDOMMemberV* lir);
+ void visitGetDOMMemberT(LGetDOMMemberT* lir);
+ void visitSetDOMProperty(LSetDOMProperty* lir);
+ void visitCallDOMNative(LCallDOMNative* lir);
+ void visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir);
+ void visitCallBindVar(LCallBindVar* lir);
+ void visitIsCallable(LIsCallable* lir);
+ void visitOutOfLineIsCallable(OutOfLineIsCallable* ool);
+ void visitIsConstructor(LIsConstructor* lir);
+ void visitOutOfLineIsConstructor(OutOfLineIsConstructor* ool);
+ void visitIsObject(LIsObject* lir);
+ void visitIsObjectAndBranch(LIsObjectAndBranch* lir);
+ void visitHasClass(LHasClass* lir);
+ void visitWasmParameter(LWasmParameter* lir);
+ void visitWasmParameterI64(LWasmParameterI64* lir);
+ void visitWasmReturn(LWasmReturn* ret);
+ void visitWasmReturnI64(LWasmReturnI64* ret);
+ void visitWasmReturnVoid(LWasmReturnVoid* 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 visitNaNToZero(LNaNToZero* ins);
+ void visitOutOfLineNaNToZero(OutOfLineNaNToZero* ool);
+
+ void visitCheckOverRecursed(LCheckOverRecursed* lir);
+ void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool);
+
+ void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir);
+ void visitOutOfLineUnboxFloatingPoint(OutOfLineUnboxFloatingPoint* ool);
+ void visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool);
+
+ void loadJSScriptForBlock(MBasicBlock* block, Register reg);
+ void loadOutermostJSScript(Register reg);
+
+ // Inline caches visitors.
+ void visitOutOfLineCache(OutOfLineUpdateCache* ool);
+
+ void visitGetPropertyCacheV(LGetPropertyCacheV* ins);
+ void visitGetPropertyCacheT(LGetPropertyCacheT* ins);
+ void visitBindNameCache(LBindNameCache* ins);
+ void visitCallSetProperty(LInstruction* ins);
+ void visitSetPropertyCache(LSetPropertyCache* ins);
+ void visitGetNameCache(LGetNameCache* ins);
+
+ void visitGetPropertyIC(OutOfLineUpdateCache* ool, DataPtr<GetPropertyIC>& ic);
+ void visitSetPropertyIC(OutOfLineUpdateCache* ool, DataPtr<SetPropertyIC>& ic);
+ void visitBindNameIC(OutOfLineUpdateCache* ool, DataPtr<BindNameIC>& ic);
+ void visitNameIC(OutOfLineUpdateCache* ool, DataPtr<NameIC>& ic);
+
+ void visitAssertRangeI(LAssertRangeI* ins);
+ void visitAssertRangeD(LAssertRangeD* ins);
+ void visitAssertRangeF(LAssertRangeF* ins);
+ void visitAssertRangeV(LAssertRangeV* ins);
+
+ void visitAssertResultV(LAssertResultV* ins);
+ void visitAssertResultT(LAssertResultT* ins);
+ void emitAssertResultV(const ValueOperand output, const TemporaryTypeSet* typeset);
+ void emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset);
+
+ void visitInterruptCheck(LInterruptCheck* lir);
+ void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins);
+ void visitWasmTrap(LWasmTrap* lir);
+ void visitWasmBoundsCheck(LWasmBoundsCheck* ins);
+ void visitRecompileCheck(LRecompileCheck* ins);
+ void visitRotate(LRotate* ins);
+
+ void visitRandom(LRandom* ins);
+ void visitSignExtend(LSignExtend* ins);
+
+#ifdef DEBUG
+ void emitDebugForceBailing(LInstruction* lir);
+#endif
+
+ IonScriptCounts* extractScriptCounts() {
+ IonScriptCounts* counts = scriptCounts_;
+ scriptCounts_ = nullptr; // prevent delete in dtor
+ return counts;
+ }
+
+ private:
+ void addGetPropertyCache(LInstruction* ins, LiveRegisterSet liveRegs, Register objReg,
+ const ConstantOrRegister& id, TypedOrValueRegister output,
+ bool monitoredResult, bool allowDoubleResult,
+ jsbytecode* profilerLeavePc);
+ void addSetPropertyCache(LInstruction* ins, LiveRegisterSet liveRegs, Register objReg,
+ Register temp, Register tempUnbox, FloatRegister tempDouble,
+ FloatRegister tempF32, const ConstantOrRegister& id,
+ const ConstantOrRegister& value,
+ bool strict, bool needsTypeBarrier, bool guardHoles,
+ jsbytecode* profilerLeavePc);
+
+ MOZ_MUST_USE bool generateBranchV(const ValueOperand& value, Label* ifTrue, Label* ifFalse,
+ FloatRegister fr);
+
+ void emitLambdaInit(Register resultReg, Register envChainReg,
+ const LambdaFunctionInfo& info);
+
+ void emitFilterArgumentsOrEval(LInstruction* lir, Register string, Register temp1,
+ Register temp2);
+
+ template <class IteratorObject, class OrderedHashTable>
+ void emitGetNextEntryForIterator(LGetNextEntryForIterator* lir);
+
+ template <class OrderedHashTable>
+ void emitLoadIteratorValues(Register result, Register temp, Register front);
+
+ IonScriptCounts* maybeCreateScriptCounts();
+
+ // This function behaves like testValueTruthy with the exception that it can
+ // choose to let control flow fall through when the object is truthy, as
+ // an optimization. Use testValueTruthy when it's required to branch to one
+ // of the two labels.
+ void testValueTruthyKernel(const ValueOperand& value,
+ const LDefinition* scratch1, const LDefinition* scratch2,
+ FloatRegister fr,
+ Label* ifTruthy, Label* ifFalsy,
+ OutOfLineTestObject* ool,
+ MDefinition* valueMIR);
+
+ // Test whether value is truthy or not and jump to the corresponding label.
+ // If the value can be an object that emulates |undefined|, |ool| must be
+ // non-null; otherwise it may be null (and the scratch definitions should
+ // be bogus), in which case an object encountered here will always be
+ // truthy.
+ void testValueTruthy(const ValueOperand& value,
+ const LDefinition* scratch1, const LDefinition* scratch2,
+ FloatRegister fr,
+ Label* ifTruthy, Label* ifFalsy,
+ OutOfLineTestObject* ool,
+ MDefinition* valueMIR);
+
+ // This function behaves like testObjectEmulatesUndefined with the exception
+ // that it can choose to let control flow fall through when the object
+ // doesn't emulate undefined, as an optimization. Use the regular
+ // testObjectEmulatesUndefined when it's required to branch to one of the
+ // two labels.
+ void testObjectEmulatesUndefinedKernel(Register objreg,
+ Label* ifEmulatesUndefined,
+ Label* ifDoesntEmulateUndefined,
+ Register scratch, OutOfLineTestObject* ool);
+
+ // Test whether an object emulates |undefined|. If it does, jump to
+ // |ifEmulatesUndefined|; the caller is responsible for binding this label.
+ // If it doesn't, fall through; the label |ifDoesntEmulateUndefined| (which
+ // must be initially unbound) will be bound at this point.
+ void branchTestObjectEmulatesUndefined(Register objreg,
+ Label* ifEmulatesUndefined,
+ Label* ifDoesntEmulateUndefined,
+ Register scratch, OutOfLineTestObject* ool);
+
+ // Test whether an object emulates |undefined|, and jump to the
+ // corresponding label.
+ //
+ // This method should be used when subsequent code can't be laid out in a
+ // straight line; if it can, branchTest* should be used instead.
+ void testObjectEmulatesUndefined(Register objreg,
+ Label* ifEmulatesUndefined,
+ Label* ifDoesntEmulateUndefined,
+ Register scratch, OutOfLineTestObject* ool);
+
+ // Branch to target unless obj has an emptyObjectElements or emptyObjectElementsShared
+ // elements pointer.
+ void branchIfNotEmptyObjectElements(Register obj, Label* target);
+
+ void emitStoreElementTyped(const LAllocation* value, MIRType valueType, MIRType elementType,
+ Register elements, const LAllocation* index,
+ int32_t offsetAdjustment);
+
+ // Bailout if an element about to be written to is a hole.
+ void emitStoreHoleCheck(Register elements, const LAllocation* index, int32_t offsetAdjustment,
+ LSnapshot* snapshot);
+
+ void emitAssertRangeI(const Range* r, Register input);
+ void emitAssertRangeD(const Range* r, FloatRegister input, FloatRegister temp);
+
+ void maybeEmitGlobalBarrierCheck(const LAllocation* maybeGlobal, OutOfLineCode* ool);
+
+ Vector<CodeOffset, 0, JitAllocPolicy> ionScriptLabels_;
+
+ struct SharedStub {
+ ICStub::Kind kind;
+ IonICEntry entry;
+ CodeOffset label;
+
+ SharedStub(ICStub::Kind kind, IonICEntry entry, CodeOffset label)
+ : kind(kind), entry(entry), label(label)
+ {}
+ };
+
+ Vector<SharedStub, 0, SystemAllocPolicy> sharedStubs_;
+
+ void branchIfInvalidated(Register temp, Label* invalidated);
+
+#ifdef DEBUG
+ void emitDebugResultChecks(LInstruction* ins);
+ void emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir);
+ void emitValueResultChecks(LInstruction* lir, MDefinition* mir);
+#endif
+
+ // Script counts created during code generation.
+ IonScriptCounts* scriptCounts_;
+
+#if defined(JS_ION_PERF)
+ PerfSpewer perfSpewer_;
+#endif
+
+ // This integer is a bit mask of all SimdTypeDescr::Type indexes. When a
+ // MSimdBox instruction is encoded, it might have either been created by
+ // IonBuilder, or by the Eager Simd Unbox phase.
+ //
+ // As the template objects are weak references, the JitCompartment is using
+ // Read Barriers, but such barrier cannot be used during the compilation. To
+ // work around this issue, the barriers are captured during
+ // CodeGenerator::link.
+ //
+ // Instead of saving the pointers, we just save the index of the Read
+ // Barriered objects in a bit mask.
+ uint32_t simdRefreshTemplatesDuringLink_;
+
+ void registerSimdTemplate(SimdType simdType);
+ void captureSimdTemplate(JSContext* cx);
+};
+
+} // namespace jit
+} // namespace js
+
+#endif /* jit_CodeGenerator_h */