1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * vim: set ts=8 sts=4 et sw=4 tw=99: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef jit_CodeGenerator_h 8 #define jit_CodeGenerator_h 9 10 #include "jit/IonCaches.h" 11 #if defined(JS_ION_PERF) 12 # include "jit/PerfSpewer.h" 13 #endif 14 15 #if defined(JS_CODEGEN_X86) 16 # include "jit/x86/CodeGenerator-x86.h" 17 #elif defined(JS_CODEGEN_X64) 18 # include "jit/x64/CodeGenerator-x64.h" 19 #elif defined(JS_CODEGEN_ARM) 20 # include "jit/arm/CodeGenerator-arm.h" 21 #elif defined(JS_CODEGEN_ARM64) 22 # include "jit/arm64/CodeGenerator-arm64.h" 23 #elif defined(JS_CODEGEN_MIPS32) 24 # include "jit/mips32/CodeGenerator-mips32.h" 25 #elif defined(JS_CODEGEN_MIPS64) 26 # include "jit/mips64/CodeGenerator-mips64.h" 27 #elif defined(JS_CODEGEN_NONE) 28 # include "jit/none/CodeGenerator-none.h" 29 #else 30 #error "Unknown architecture!" 31 #endif 32 33 namespace js { 34 namespace jit { 35 36 class OutOfLineTestObject; 37 class OutOfLineNewArray; 38 class OutOfLineNewObject; 39 class CheckOverRecursedFailure; 40 class OutOfLineInterruptCheckImplicit; 41 class OutOfLineUnboxFloatingPoint; 42 class OutOfLineStoreElementHole; 43 class OutOfLineTypeOfV; 44 class OutOfLineUpdateCache; 45 class OutOfLineCallPostWriteBarrier; 46 class OutOfLineIsCallable; 47 class OutOfLineRegExpExec; 48 class OutOfLineRegExpTest; 49 class OutOfLineLambdaArrow; 50 51 class CodeGenerator : public CodeGeneratorSpecific 52 { 53 void generateArgumentsChecks(bool bailout = true); 54 bool generateBody(); 55 56 ConstantOrRegister toConstantOrRegister(LInstruction* lir, size_t n, MIRType type); 57 58 public: 59 CodeGenerator(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm = nullptr); 60 ~CodeGenerator(); 61 62 public: 63 bool generate(); 64 bool generateAsmJS(AsmJSFunctionOffsets *offsets); 65 bool link(JSContext* cx, CompilerConstraintList* constraints); 66 bool linkSharedStubs(JSContext* cx); 67 68 void visitOsiPoint(LOsiPoint* lir); 69 void visitGoto(LGoto* lir); 70 void visitTableSwitch(LTableSwitch* ins); 71 void visitTableSwitchV(LTableSwitchV* ins); 72 void visitCloneLiteral(LCloneLiteral* lir); 73 void visitParameter(LParameter* lir); 74 void visitCallee(LCallee* lir); 75 void visitIsConstructing(LIsConstructing* lir); 76 void visitStart(LStart* lir); 77 void visitReturn(LReturn* ret); 78 void visitDefVar(LDefVar* lir); 79 void visitDefLexical(LDefLexical* lir); 80 void visitDefFun(LDefFun* lir); 81 void visitOsrEntry(LOsrEntry* lir); 82 void visitOsrScopeChain(LOsrScopeChain* lir); 83 void visitOsrValue(LOsrValue* lir); 84 void visitOsrReturnValue(LOsrReturnValue* lir); 85 void visitOsrArgumentsObject(LOsrArgumentsObject* lir); 86 void visitStackArgT(LStackArgT* lir); 87 void visitStackArgV(LStackArgV* lir); 88 void visitMoveGroup(LMoveGroup* group); 89 void visitValueToInt32(LValueToInt32* lir); 90 void visitValueToDouble(LValueToDouble* lir); 91 void visitValueToFloat32(LValueToFloat32* lir); 92 void visitFloat32ToDouble(LFloat32ToDouble* lir); 93 void visitDoubleToFloat32(LDoubleToFloat32* lir); 94 void visitInt32ToFloat32(LInt32ToFloat32* lir); 95 void visitInt32ToDouble(LInt32ToDouble* lir); 96 void emitOOLTestObject(Register objreg, Label* ifTruthy, Label* ifFalsy, Register scratch); 97 void visitTestOAndBranch(LTestOAndBranch* lir); 98 void visitTestVAndBranch(LTestVAndBranch* lir); 99 void visitFunctionDispatch(LFunctionDispatch* lir); 100 void visitObjectGroupDispatch(LObjectGroupDispatch* lir); 101 void visitBooleanToString(LBooleanToString* lir); 102 void emitIntToString(Register input, Register output, Label* ool); 103 void visitIntToString(LIntToString* lir); 104 void visitDoubleToString(LDoubleToString* lir); 105 void visitValueToString(LValueToString* lir); 106 void visitValueToObjectOrNull(LValueToObjectOrNull* lir); 107 void visitInteger(LInteger* lir); 108 void visitRegExp(LRegExp* lir); 109 void visitRegExpExec(LRegExpExec* lir); 110 void visitOutOfLineRegExpExec(OutOfLineRegExpExec* ool); 111 void visitRegExpTest(LRegExpTest* lir); 112 void visitOutOfLineRegExpTest(OutOfLineRegExpTest* ool); 113 void visitRegExpReplace(LRegExpReplace* lir); 114 void visitStringReplace(LStringReplace* lir); 115 void emitSharedStub(ICStub::Kind kind, LInstruction* lir); 116 void visitBinarySharedStub(LBinarySharedStub* lir); 117 void visitUnarySharedStub(LUnarySharedStub* lir); 118 void visitLambda(LLambda* lir); 119 void visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool); 120 void visitLambdaArrow(LLambdaArrow* lir); 121 void visitLambdaForSingleton(LLambdaForSingleton* lir); 122 void visitPointer(LPointer* lir); 123 void visitKeepAliveObject(LKeepAliveObject* lir); 124 void visitSlots(LSlots* lir); 125 void visitLoadSlotT(LLoadSlotT* lir); 126 void visitLoadSlotV(LLoadSlotV* lir); 127 void visitStoreSlotT(LStoreSlotT* lir); 128 void visitStoreSlotV(LStoreSlotV* lir); 129 void visitElements(LElements* lir); 130 void visitConvertElementsToDoubles(LConvertElementsToDoubles* lir); 131 void visitMaybeToDoubleElement(LMaybeToDoubleElement* lir); 132 void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir); 133 void visitGuardObjectIdentity(LGuardObjectIdentity* guard); 134 void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir); 135 void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir); 136 void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir); 137 void visitTypeBarrierV(LTypeBarrierV* lir); 138 void visitTypeBarrierO(LTypeBarrierO* lir); 139 void visitMonitorTypes(LMonitorTypes* lir); 140 void visitPostWriteBarrierO(LPostWriteBarrierO* lir); 141 void visitPostWriteBarrierV(LPostWriteBarrierV* lir); 142 void visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier* ool); 143 void visitCallNative(LCallNative* call); 144 void emitCallInvokeFunction(LInstruction* call, Register callereg, 145 bool isConstructing, uint32_t argc, 146 uint32_t unusedStack); 147 void visitCallGeneric(LCallGeneric* call); 148 void emitCallInvokeFunctionShuffleNewTarget(LCallKnown *call, 149 Register calleeReg, 150 uint32_t numFormals, 151 uint32_t unusedStack); 152 void visitCallKnown(LCallKnown* call); 153 template<typename T> void emitApplyGeneric(T* apply); 154 template<typename T> void emitCallInvokeFunction(T* apply, Register extraStackSize); 155 void emitAllocateSpaceForApply(Register argcreg, Register extraStackSpace, Label* end); 156 void emitCopyValuesForApply(Register argvSrcBase, Register argvIndex, Register copyreg, 157 size_t argvSrcOffset, size_t argvDstOffset); 158 void emitPopArguments(Register extraStackSize); 159 void emitPushArguments(LApplyArgsGeneric* apply, Register extraStackSpace); 160 void visitApplyArgsGeneric(LApplyArgsGeneric* apply); 161 void emitPushArguments(LApplyArrayGeneric* apply, Register extraStackSpace); 162 void visitApplyArrayGeneric(LApplyArrayGeneric* apply); 163 void visitBail(LBail* lir); 164 void visitUnreachable(LUnreachable* unreachable); 165 void visitEncodeSnapshot(LEncodeSnapshot* lir); 166 void visitGetDynamicName(LGetDynamicName* lir); 167 void visitCallDirectEval(LCallDirectEval* lir); 168 void visitDoubleToInt32(LDoubleToInt32* lir); 169 void visitFloat32ToInt32(LFloat32ToInt32* lir); 170 void visitNewArrayCallVM(LNewArray* lir); 171 void visitNewArray(LNewArray* lir); 172 void visitOutOfLineNewArray(OutOfLineNewArray* ool); 173 void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir); 174 void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir); 175 void visitNewObjectVMCall(LNewObject* lir); 176 void visitNewObject(LNewObject* lir); 177 void visitOutOfLineNewObject(OutOfLineNewObject* ool); 178 void visitNewTypedObject(LNewTypedObject* lir); 179 void visitSimdBox(LSimdBox* lir); 180 void visitSimdUnbox(LSimdUnbox* lir); 181 void visitNewDeclEnvObject(LNewDeclEnvObject* lir); 182 void visitNewCallObject(LNewCallObject* lir); 183 void visitNewSingletonCallObject(LNewSingletonCallObject* lir); 184 void visitNewStringObject(LNewStringObject* lir); 185 void visitNewDerivedTypedObject(LNewDerivedTypedObject* lir); 186 void visitInitElem(LInitElem* lir); 187 void visitInitElemGetterSetter(LInitElemGetterSetter* lir); 188 void visitMutateProto(LMutateProto* lir); 189 void visitInitProp(LInitProp* lir); 190 void visitInitPropGetterSetter(LInitPropGetterSetter* lir); 191 void visitCreateThis(LCreateThis* lir); 192 void visitCreateThisWithProto(LCreateThisWithProto* lir); 193 void visitCreateThisWithTemplate(LCreateThisWithTemplate* lir); 194 void visitCreateArgumentsObject(LCreateArgumentsObject* lir); 195 void visitGetArgumentsObjectArg(LGetArgumentsObjectArg* lir); 196 void visitSetArgumentsObjectArg(LSetArgumentsObjectArg* lir); 197 void visitReturnFromCtor(LReturnFromCtor* lir); 198 void visitComputeThis(LComputeThis* lir); 199 void visitArrayLength(LArrayLength* lir); 200 void visitSetArrayLength(LSetArrayLength* lir); 201 void visitTypedArrayLength(LTypedArrayLength* lir); 202 void visitTypedArrayElements(LTypedArrayElements* lir); 203 void visitSetDisjointTypedElements(LSetDisjointTypedElements* lir); 204 void visitTypedObjectElements(LTypedObjectElements* lir); 205 void visitSetTypedObjectOffset(LSetTypedObjectOffset* lir); 206 void visitTypedObjectDescr(LTypedObjectDescr* ins); 207 void visitStringLength(LStringLength* lir); 208 void visitSubstr(LSubstr* lir); 209 void visitInitializedLength(LInitializedLength* lir); 210 void visitSetInitializedLength(LSetInitializedLength* lir); 211 void visitUnboxedArrayLength(LUnboxedArrayLength* lir); 212 void visitUnboxedArrayInitializedLength(LUnboxedArrayInitializedLength* lir); 213 void visitIncrementUnboxedArrayInitializedLength(LIncrementUnboxedArrayInitializedLength* lir); 214 void visitSetUnboxedArrayInitializedLength(LSetUnboxedArrayInitializedLength* lir); 215 void visitNotO(LNotO* ins); 216 void visitNotV(LNotV* ins); 217 void visitBoundsCheck(LBoundsCheck* lir); 218 void visitBoundsCheckRange(LBoundsCheckRange* lir); 219 void visitBoundsCheckLower(LBoundsCheckLower* lir); 220 void visitLoadFixedSlotV(LLoadFixedSlotV* ins); 221 void visitLoadFixedSlotAndUnbox(LLoadFixedSlotAndUnbox* lir); 222 void visitLoadFixedSlotT(LLoadFixedSlotT* ins); 223 void visitStoreFixedSlotV(LStoreFixedSlotV* ins); 224 void visitStoreFixedSlotT(LStoreFixedSlotT* ins); 225 void emitGetPropertyPolymorphic(LInstruction* lir, Register obj, 226 Register scratch, const TypedOrValueRegister& output); 227 void visitGetPropertyPolymorphicV(LGetPropertyPolymorphicV* ins); 228 void visitGetPropertyPolymorphicT(LGetPropertyPolymorphicT* ins); 229 void emitSetPropertyPolymorphic(LInstruction* lir, Register obj, 230 Register scratch, const ConstantOrRegister& value); 231 void visitSetPropertyPolymorphicV(LSetPropertyPolymorphicV* ins); 232 void visitArraySplice(LArraySplice* splice); 233 void visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins); 234 void visitAbsI(LAbsI* lir); 235 void visitAtan2D(LAtan2D* lir); 236 void visitHypot(LHypot* lir); 237 void visitPowI(LPowI* lir); 238 void visitPowD(LPowD* lir); 239 void visitMathFunctionD(LMathFunctionD* ins); 240 void visitMathFunctionF(LMathFunctionF* ins); 241 void visitModD(LModD* ins); 242 void visitMinMaxI(LMinMaxI* lir); 243 void visitBinaryV(LBinaryV* lir); 244 void emitCompareS(LInstruction* lir, JSOp op, Register left, Register right, Register output); 245 void visitCompareS(LCompareS* lir); 246 void visitCompareStrictS(LCompareStrictS* lir); 247 void visitCompareVM(LCompareVM* lir); 248 void visitIsNullOrLikeUndefinedV(LIsNullOrLikeUndefinedV* lir); 249 void visitIsNullOrLikeUndefinedT(LIsNullOrLikeUndefinedT* lir); 250 void visitIsNullOrLikeUndefinedAndBranchV(LIsNullOrLikeUndefinedAndBranchV* lir); 251 void visitIsNullOrLikeUndefinedAndBranchT(LIsNullOrLikeUndefinedAndBranchT* lir); 252 void emitConcat(LInstruction* lir, Register lhs, Register rhs, Register output); 253 void visitConcat(LConcat* lir); 254 void visitCharCodeAt(LCharCodeAt* lir); 255 void visitFromCharCode(LFromCharCode* lir); 256 void visitSinCos(LSinCos *lir); 257 void visitStringSplit(LStringSplit* lir); 258 void visitFunctionEnvironment(LFunctionEnvironment* lir); 259 void visitCallGetProperty(LCallGetProperty* lir); 260 void visitCallGetElement(LCallGetElement* lir); 261 void visitCallSetElement(LCallSetElement* lir); 262 void visitCallInitElementArray(LCallInitElementArray* lir); 263 void visitThrow(LThrow* lir); 264 void visitTypeOfV(LTypeOfV* lir); 265 void visitOutOfLineTypeOfV(OutOfLineTypeOfV* ool); 266 void visitToIdV(LToIdV* lir); 267 template<typename T> void emitLoadElementT(LLoadElementT* lir, const T& source); 268 void visitLoadElementT(LLoadElementT* lir); 269 void visitLoadElementV(LLoadElementV* load); 270 void visitLoadElementHole(LLoadElementHole* lir); 271 void visitLoadUnboxedPointerV(LLoadUnboxedPointerV* lir); 272 void visitLoadUnboxedPointerT(LLoadUnboxedPointerT* lir); 273 void visitUnboxObjectOrNull(LUnboxObjectOrNull* lir); 274 void visitStoreElementT(LStoreElementT* lir); 275 void visitStoreElementV(LStoreElementV* lir); 276 void visitStoreElementHoleT(LStoreElementHoleT* lir); 277 void visitStoreElementHoleV(LStoreElementHoleV* lir); 278 void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir); 279 void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir); 280 void emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, Register obj, 281 Register elementsTemp, Register lengthTemp, TypedOrValueRegister out); 282 void visitArrayPopShiftV(LArrayPopShiftV* lir); 283 void visitArrayPopShiftT(LArrayPopShiftT* lir); 284 void emitArrayPush(LInstruction* lir, const MArrayPush* mir, Register obj, 285 ConstantOrRegister value, Register elementsTemp, Register length); 286 void visitArrayPushV(LArrayPushV* lir); 287 void visitArrayPushT(LArrayPushT* lir); 288 void visitArrayConcat(LArrayConcat* lir); 289 void visitArraySlice(LArraySlice* lir); 290 void visitArrayJoin(LArrayJoin* lir); 291 void visitLoadUnboxedScalar(LLoadUnboxedScalar* lir); 292 void visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir); 293 void visitStoreUnboxedScalar(LStoreUnboxedScalar* lir); 294 void visitStoreTypedArrayElementHole(LStoreTypedArrayElementHole* lir); 295 void visitAtomicIsLockFree(LAtomicIsLockFree* lir); 296 void visitGuardSharedTypedArray(LGuardSharedTypedArray* lir); 297 void visitClampIToUint8(LClampIToUint8* lir); 298 void visitClampDToUint8(LClampDToUint8* lir); 299 void visitClampVToUint8(LClampVToUint8* lir); 300 void visitCallIteratorStart(LCallIteratorStart* lir); 301 void visitIteratorStart(LIteratorStart* lir); 302 void visitIteratorMore(LIteratorMore* lir); 303 void visitIsNoIterAndBranch(LIsNoIterAndBranch* lir); 304 void visitIteratorEnd(LIteratorEnd* lir); 305 void visitArgumentsLength(LArgumentsLength* lir); 306 void visitGetFrameArgument(LGetFrameArgument* lir); 307 void visitSetFrameArgumentT(LSetFrameArgumentT* lir); 308 void visitSetFrameArgumentC(LSetFrameArgumentC* lir); 309 void visitSetFrameArgumentV(LSetFrameArgumentV* lir); 310 void visitRunOncePrologue(LRunOncePrologue* lir); 311 void emitRest(LInstruction* lir, Register array, Register numActuals, 312 Register temp0, Register temp1, unsigned numFormals, 313 JSObject* templateObject, bool saveAndRestore, Register resultreg); 314 void visitRest(LRest* lir); 315 void visitCallSetProperty(LCallSetProperty* ins); 316 void visitCallDeleteProperty(LCallDeleteProperty* lir); 317 void visitCallDeleteElement(LCallDeleteElement* lir); 318 void visitBitNotV(LBitNotV* lir); 319 void visitBitOpV(LBitOpV* lir); 320 void emitInstanceOf(LInstruction* ins, JSObject* prototypeObject); 321 void visitIn(LIn* ins); 322 void visitInArray(LInArray* ins); 323 void visitInstanceOfO(LInstanceOfO* ins); 324 void visitInstanceOfV(LInstanceOfV* ins); 325 void visitCallInstanceOf(LCallInstanceOf* ins); 326 void visitGetDOMProperty(LGetDOMProperty* lir); 327 void visitGetDOMMemberV(LGetDOMMemberV* lir); 328 void visitGetDOMMemberT(LGetDOMMemberT* lir); 329 void visitSetDOMProperty(LSetDOMProperty* lir); 330 void visitCallDOMNative(LCallDOMNative* lir); 331 void visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir); 332 void visitIsCallable(LIsCallable* lir); 333 void visitOutOfLineIsCallable(OutOfLineIsCallable* ool); 334 void visitIsObject(LIsObject* lir); 335 void visitIsObjectAndBranch(LIsObjectAndBranch* lir); 336 void visitHasClass(LHasClass* lir); 337 void visitAsmJSParameter(LAsmJSParameter* lir); 338 void visitAsmJSReturn(LAsmJSReturn* ret); 339 void visitAsmJSVoidReturn(LAsmJSVoidReturn* ret); 340 void visitLexicalCheck(LLexicalCheck* ins); 341 void visitThrowRuntimeLexicalError(LThrowRuntimeLexicalError* ins); 342 void visitGlobalNameConflictsCheck(LGlobalNameConflictsCheck* ins); 343 void visitDebugger(LDebugger* ins); 344 void visitNewTarget(LNewTarget* ins); 345 void visitArrowNewTarget(LArrowNewTarget* ins); 346 void visitCheckReturn(LCheckReturn* ins); 347 void visitCheckObjCoercible(LCheckObjCoercible* ins); 348 349 void visitCheckOverRecursed(LCheckOverRecursed* lir); 350 void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool); 351 352 void visitInterruptCheckImplicit(LInterruptCheckImplicit* ins); 353 void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins); 354 355 void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir); 356 void visitOutOfLineUnboxFloatingPoint(OutOfLineUnboxFloatingPoint* ool); 357 void visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool); 358 359 void loadJSScriptForBlock(MBasicBlock* block, Register reg); 360 void loadOutermostJSScript(Register reg); 361 362 // Inline caches visitors. 363 void visitOutOfLineCache(OutOfLineUpdateCache* ool); 364 365 void visitGetPropertyCacheV(LGetPropertyCacheV* ins); 366 void visitGetPropertyCacheT(LGetPropertyCacheT* ins); 367 void visitBindNameCache(LBindNameCache* ins); 368 void visitCallSetProperty(LInstruction* ins); 369 void visitSetPropertyCache(LSetPropertyCache* ins); 370 void visitGetNameCache(LGetNameCache* ins); 371 372 void visitGetPropertyIC(OutOfLineUpdateCache* ool, DataPtr<GetPropertyIC>& ic); 373 void visitSetPropertyIC(OutOfLineUpdateCache* ool, DataPtr<SetPropertyIC>& ic); 374 void visitBindNameIC(OutOfLineUpdateCache* ool, DataPtr<BindNameIC>& ic); 375 void visitNameIC(OutOfLineUpdateCache* ool, DataPtr<NameIC>& ic); 376 377 void visitAssertRangeI(LAssertRangeI* ins); 378 void visitAssertRangeD(LAssertRangeD* ins); 379 void visitAssertRangeF(LAssertRangeF* ins); 380 void visitAssertRangeV(LAssertRangeV* ins); 381 382 void visitAssertResultV(LAssertResultV* ins); 383 void visitAssertResultT(LAssertResultT* ins); 384 void emitAssertResultV(const ValueOperand output, const TemporaryTypeSet* typeset); 385 void emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset); 386 387 void visitInterruptCheck(LInterruptCheck* lir); 388 void visitAsmJSInterruptCheck(LAsmJSInterruptCheck* lir); 389 void visitRecompileCheck(LRecompileCheck* ins); 390 391 void visitRandom(LRandom* ins); 392 extractScriptCounts()393 IonScriptCounts* extractScriptCounts() { 394 IonScriptCounts* counts = scriptCounts_; 395 scriptCounts_ = nullptr; // prevent delete in dtor 396 return counts; 397 } 398 399 private: 400 void addGetPropertyCache(LInstruction* ins, LiveRegisterSet liveRegs, Register objReg, 401 ConstantOrRegister id, TypedOrValueRegister output, 402 bool monitoredResult, bool allowDoubleResult, 403 jsbytecode* profilerLeavePc); 404 void addSetPropertyCache(LInstruction* ins, LiveRegisterSet liveRegs, Register objReg, 405 Register temp, Register tempUnbox, FloatRegister tempDouble, 406 FloatRegister tempF32, ConstantOrRegister id, ConstantOrRegister value, 407 bool strict, bool needsTypeBarrier, bool guardHoles, 408 jsbytecode* profilerLeavePc); 409 410 bool generateBranchV(const ValueOperand& value, Label* ifTrue, Label* ifFalse, FloatRegister fr); 411 412 void emitLambdaInit(Register resultReg, Register scopeChainReg, 413 const LambdaFunctionInfo& info); 414 415 void emitFilterArgumentsOrEval(LInstruction* lir, Register string, Register temp1, 416 Register temp2); 417 418 IonScriptCounts* maybeCreateScriptCounts(); 419 420 // This function behaves like testValueTruthy with the exception that it can 421 // choose to let control flow fall through when the object is truthy, as 422 // an optimization. Use testValueTruthy when it's required to branch to one 423 // of the two labels. 424 void testValueTruthyKernel(const ValueOperand& value, 425 const LDefinition* scratch1, const LDefinition* scratch2, 426 FloatRegister fr, 427 Label* ifTruthy, Label* ifFalsy, 428 OutOfLineTestObject* ool, 429 MDefinition* valueMIR); 430 431 // Test whether value is truthy or not and jump to the corresponding label. 432 // If the value can be an object that emulates |undefined|, |ool| must be 433 // non-null; otherwise it may be null (and the scratch definitions should 434 // be bogus), in which case an object encountered here will always be 435 // truthy. 436 void testValueTruthy(const ValueOperand& value, 437 const LDefinition* scratch1, const LDefinition* scratch2, 438 FloatRegister fr, 439 Label* ifTruthy, Label* ifFalsy, 440 OutOfLineTestObject* ool, 441 MDefinition* valueMIR); 442 443 // This function behaves like testObjectEmulatesUndefined with the exception 444 // that it can choose to let control flow fall through when the object 445 // doesn't emulate undefined, as an optimization. Use the regular 446 // testObjectEmulatesUndefined when it's required to branch to one of the 447 // two labels. 448 void testObjectEmulatesUndefinedKernel(Register objreg, 449 Label* ifEmulatesUndefined, 450 Label* ifDoesntEmulateUndefined, 451 Register scratch, OutOfLineTestObject* ool); 452 453 // Test whether an object emulates |undefined|. If it does, jump to 454 // |ifEmulatesUndefined|; the caller is responsible for binding this label. 455 // If it doesn't, fall through; the label |ifDoesntEmulateUndefined| (which 456 // must be initially unbound) will be bound at this point. 457 void branchTestObjectEmulatesUndefined(Register objreg, 458 Label* ifEmulatesUndefined, 459 Label* ifDoesntEmulateUndefined, 460 Register scratch, OutOfLineTestObject* ool); 461 462 // Test whether an object emulates |undefined|, and jump to the 463 // corresponding label. 464 // 465 // This method should be used when subsequent code can't be laid out in a 466 // straight line; if it can, branchTest* should be used instead. 467 void testObjectEmulatesUndefined(Register objreg, 468 Label* ifEmulatesUndefined, 469 Label* ifDoesntEmulateUndefined, 470 Register scratch, OutOfLineTestObject* ool); 471 472 // Branch to target unless obj has an emptyObjectElements or emptyObjectElementsShared 473 // elements pointer. 474 void branchIfNotEmptyObjectElements(Register obj, Label* target); 475 476 // Get a label for the start of block which can be used for jumping, in 477 // place of jumpToBlock. 478 Label* getJumpLabelForBranch(MBasicBlock* block); 479 480 void emitStoreElementTyped(const LAllocation* value, MIRType valueType, MIRType elementType, 481 Register elements, const LAllocation* index, 482 int32_t offsetAdjustment); 483 484 // Bailout if an element about to be written to is a hole. 485 void emitStoreHoleCheck(Register elements, const LAllocation* index, int32_t offsetAdjustment, 486 LSnapshot* snapshot); 487 488 void emitAssertRangeI(const Range* r, Register input); 489 void emitAssertRangeD(const Range* r, FloatRegister input, FloatRegister temp); 490 491 Vector<CodeOffset, 0, JitAllocPolicy> ionScriptLabels_; 492 493 struct SharedStub { 494 ICStub::Kind kind; 495 IonICEntry entry; 496 CodeOffset label; 497 SharedStubSharedStub498 SharedStub(ICStub::Kind kind, IonICEntry entry, CodeOffset label) 499 : kind(kind), entry(entry), label(label) 500 {} 501 }; 502 503 Vector<SharedStub, 0, SystemAllocPolicy> sharedStubs_; 504 505 void branchIfInvalidated(Register temp, Label* invalidated); 506 507 #ifdef DEBUG 508 void emitDebugResultChecks(LInstruction* ins); 509 void emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir); 510 void emitValueResultChecks(LInstruction* lir, MDefinition* mir); 511 #endif 512 513 // Script counts created during code generation. 514 IonScriptCounts* scriptCounts_; 515 516 #if defined(JS_ION_PERF) 517 PerfSpewer perfSpewer_; 518 #endif 519 520 // This integer is a bit mask of all SimdTypeDescr::Type indexes. When a 521 // MSimdBox instruction is encoded, it might have either been created by 522 // IonBuilder, or by the Eager Simd Unbox phase. 523 // 524 // As the template objects are weak references, the JitCompartment is using 525 // Read Barriers, but such barrier cannot be used during the compilation. To 526 // work around this issue, the barriers are captured during 527 // CodeGenerator::link. 528 // 529 // Instead of saving the pointers, we just save the index of the Read 530 // Barriered objects in a bit mask. 531 uint32_t simdRefreshTemplatesDuringLink_; 532 533 void registerSimdTemplate(InlineTypedObject* templateObject); 534 void captureSimdTemplate(JSContext* cx); 535 }; 536 537 } // namespace jit 538 } // namespace js 539 540 #endif /* jit_CodeGenerator_h */ 541