Line data Source code
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 OutOfLineICFallback;
46 : class OutOfLineCallPostWriteBarrier;
47 : class OutOfLineCallPostWriteElementBarrier;
48 : class OutOfLineIsCallable;
49 : class OutOfLineIsConstructor;
50 : class OutOfLineRegExpMatcher;
51 : class OutOfLineRegExpSearcher;
52 : class OutOfLineRegExpTester;
53 : class OutOfLineRegExpPrototypeOptimizable;
54 : class OutOfLineRegExpInstanceOptimizable;
55 : class OutOfLineLambdaArrow;
56 : class OutOfLineNaNToZero;
57 :
58 : class CodeGenerator final : public CodeGeneratorSpecific
59 : {
60 : void generateArgumentsChecks(bool bailout = true);
61 : MOZ_MUST_USE bool generateBody();
62 :
63 : ConstantOrRegister toConstantOrRegister(LInstruction* lir, size_t n, MIRType type);
64 :
65 : public:
66 : CodeGenerator(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm = nullptr);
67 : ~CodeGenerator();
68 :
69 : public:
70 : MOZ_MUST_USE bool generate();
71 : MOZ_MUST_USE bool generateWasm(wasm::SigIdDesc sigId, wasm::BytecodeOffset trapOffset,
72 : wasm::FuncOffsets* offsets);
73 : MOZ_MUST_USE bool link(JSContext* cx, CompilerConstraintList* constraints);
74 : MOZ_MUST_USE bool linkSharedStubs(JSContext* cx);
75 :
76 : void visitOsiPoint(LOsiPoint* lir);
77 : void visitGoto(LGoto* lir);
78 : void visitTableSwitch(LTableSwitch* ins);
79 : void visitTableSwitchV(LTableSwitchV* ins);
80 : void visitCloneLiteral(LCloneLiteral* lir);
81 : void visitParameter(LParameter* lir);
82 : void visitCallee(LCallee* lir);
83 : void visitIsConstructing(LIsConstructing* lir);
84 : void visitStart(LStart* lir);
85 : void visitReturn(LReturn* ret);
86 : void visitDefVar(LDefVar* lir);
87 : void visitDefLexical(LDefLexical* lir);
88 : void visitDefFun(LDefFun* lir);
89 : void visitOsrEntry(LOsrEntry* lir);
90 : void visitOsrEnvironmentChain(LOsrEnvironmentChain* lir);
91 : void visitOsrValue(LOsrValue* lir);
92 : void visitOsrReturnValue(LOsrReturnValue* lir);
93 : void visitOsrArgumentsObject(LOsrArgumentsObject* lir);
94 : void visitStackArgT(LStackArgT* lir);
95 : void visitStackArgV(LStackArgV* lir);
96 : void visitMoveGroup(LMoveGroup* group);
97 : void visitValueToInt32(LValueToInt32* lir);
98 : void visitValueToDouble(LValueToDouble* lir);
99 : void visitValueToFloat32(LValueToFloat32* lir);
100 : void visitFloat32ToDouble(LFloat32ToDouble* lir);
101 : void visitDoubleToFloat32(LDoubleToFloat32* lir);
102 : void visitInt32ToFloat32(LInt32ToFloat32* lir);
103 : void visitInt32ToDouble(LInt32ToDouble* lir);
104 : void emitOOLTestObject(Register objreg, Label* ifTruthy, Label* ifFalsy, Register scratch);
105 : void visitTestOAndBranch(LTestOAndBranch* lir);
106 : void visitTestVAndBranch(LTestVAndBranch* lir);
107 : void visitFunctionDispatch(LFunctionDispatch* lir);
108 : void visitObjectGroupDispatch(LObjectGroupDispatch* lir);
109 : void visitBooleanToString(LBooleanToString* lir);
110 : void emitIntToString(Register input, Register output, Label* ool);
111 : void visitIntToString(LIntToString* lir);
112 : void visitDoubleToString(LDoubleToString* lir);
113 : void visitValueToString(LValueToString* lir);
114 : void visitValueToObjectOrNull(LValueToObjectOrNull* lir);
115 : void visitInteger(LInteger* lir);
116 : void visitInteger64(LInteger64* lir);
117 : void visitRegExp(LRegExp* lir);
118 : void visitRegExpMatcher(LRegExpMatcher* lir);
119 : void visitOutOfLineRegExpMatcher(OutOfLineRegExpMatcher* ool);
120 : void visitRegExpSearcher(LRegExpSearcher* lir);
121 : void visitOutOfLineRegExpSearcher(OutOfLineRegExpSearcher* ool);
122 : void visitRegExpTester(LRegExpTester* lir);
123 : void visitOutOfLineRegExpTester(OutOfLineRegExpTester* ool);
124 : void visitRegExpPrototypeOptimizable(LRegExpPrototypeOptimizable* lir);
125 : void visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototypeOptimizable* ool);
126 : void visitRegExpInstanceOptimizable(LRegExpInstanceOptimizable* lir);
127 : void visitOutOfLineRegExpInstanceOptimizable(OutOfLineRegExpInstanceOptimizable* ool);
128 : void visitGetFirstDollarIndex(LGetFirstDollarIndex* lir);
129 : void visitStringReplace(LStringReplace* lir);
130 : void emitSharedStub(ICStub::Kind kind, LInstruction* lir);
131 : void visitBinarySharedStub(LBinarySharedStub* lir);
132 : void visitUnarySharedStub(LUnarySharedStub* lir);
133 : void visitNullarySharedStub(LNullarySharedStub* lir);
134 : void visitLambda(LLambda* lir);
135 : void visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool);
136 : void visitLambdaArrow(LLambdaArrow* lir);
137 : void visitLambdaForSingleton(LLambdaForSingleton* lir);
138 : void visitSetFunName(LSetFunName* lir);
139 : void visitPointer(LPointer* lir);
140 : void visitKeepAliveObject(LKeepAliveObject* lir);
141 : void visitSlots(LSlots* lir);
142 : void visitLoadSlotT(LLoadSlotT* lir);
143 : void visitLoadSlotV(LLoadSlotV* lir);
144 : void visitStoreSlotT(LStoreSlotT* lir);
145 : void visitStoreSlotV(LStoreSlotV* lir);
146 : void visitElements(LElements* lir);
147 : void visitConvertElementsToDoubles(LConvertElementsToDoubles* lir);
148 : void visitMaybeToDoubleElement(LMaybeToDoubleElement* lir);
149 : void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir);
150 : void visitGuardObjectIdentity(LGuardObjectIdentity* guard);
151 : void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir);
152 : void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir);
153 : void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir);
154 : void visitTypeBarrierV(LTypeBarrierV* lir);
155 : void visitTypeBarrierO(LTypeBarrierO* lir);
156 : void visitMonitorTypes(LMonitorTypes* lir);
157 : void emitPostWriteBarrier(const LAllocation* obj);
158 : void emitPostWriteBarrier(Register objreg);
159 : template <class LPostBarrierType>
160 : void visitPostWriteBarrierCommonO(LPostBarrierType* lir, OutOfLineCode* ool);
161 : template <class LPostBarrierType>
162 : void visitPostWriteBarrierCommonV(LPostBarrierType* lir, OutOfLineCode* ool);
163 : void visitPostWriteBarrierO(LPostWriteBarrierO* lir);
164 : void visitPostWriteElementBarrierO(LPostWriteElementBarrierO* lir);
165 : void visitPostWriteBarrierV(LPostWriteBarrierV* lir);
166 : void visitPostWriteElementBarrierV(LPostWriteElementBarrierV* lir);
167 : void visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier* ool);
168 : void visitOutOfLineCallPostWriteElementBarrier(OutOfLineCallPostWriteElementBarrier* ool);
169 : void visitCallNative(LCallNative* call);
170 : void emitCallInvokeFunction(LInstruction* call, Register callereg,
171 : bool isConstructing, bool ignoresReturnValue,
172 : uint32_t argc, uint32_t unusedStack);
173 : void visitCallGeneric(LCallGeneric* call);
174 : void emitCallInvokeFunctionShuffleNewTarget(LCallKnown *call,
175 : Register calleeReg,
176 : uint32_t numFormals,
177 : uint32_t unusedStack);
178 : void visitCallKnown(LCallKnown* call);
179 : template<typename T> void emitApplyGeneric(T* apply);
180 : template<typename T> void emitCallInvokeFunction(T* apply, Register extraStackSize);
181 : void emitAllocateSpaceForApply(Register argcreg, Register extraStackSpace, Label* end);
182 : void emitCopyValuesForApply(Register argvSrcBase, Register argvIndex, Register copyreg,
183 : size_t argvSrcOffset, size_t argvDstOffset);
184 : void emitPopArguments(Register extraStackSize);
185 : void emitPushArguments(LApplyArgsGeneric* apply, Register extraStackSpace);
186 : void visitApplyArgsGeneric(LApplyArgsGeneric* apply);
187 : void emitPushArguments(LApplyArrayGeneric* apply, Register extraStackSpace);
188 : void visitApplyArrayGeneric(LApplyArrayGeneric* apply);
189 : void visitBail(LBail* lir);
190 : void visitUnreachable(LUnreachable* unreachable);
191 : void visitEncodeSnapshot(LEncodeSnapshot* lir);
192 : void visitGetDynamicName(LGetDynamicName* lir);
193 : void visitCallDirectEval(LCallDirectEval* lir);
194 : void visitDoubleToInt32(LDoubleToInt32* lir);
195 : void visitFloat32ToInt32(LFloat32ToInt32* lir);
196 : void visitNewArrayCallVM(LNewArray* lir);
197 : void visitNewArray(LNewArray* lir);
198 : void visitOutOfLineNewArray(OutOfLineNewArray* ool);
199 : void visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir);
200 : void visitNewArrayDynamicLength(LNewArrayDynamicLength* lir);
201 : void visitNewIterator(LNewIterator* lir);
202 : void visitNewTypedArray(LNewTypedArray* lir);
203 : void visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir);
204 : void visitNewObjectVMCall(LNewObject* lir);
205 : void visitNewObject(LNewObject* lir);
206 : void visitOutOfLineNewObject(OutOfLineNewObject* ool);
207 : void visitNewTypedObject(LNewTypedObject* lir);
208 : void visitSimdBox(LSimdBox* lir);
209 : void visitSimdUnbox(LSimdUnbox* lir);
210 : void visitNewNamedLambdaObject(LNewNamedLambdaObject* lir);
211 : void visitNewCallObject(LNewCallObject* lir);
212 : void visitNewSingletonCallObject(LNewSingletonCallObject* lir);
213 : void visitNewStringObject(LNewStringObject* lir);
214 : void visitNewDerivedTypedObject(LNewDerivedTypedObject* lir);
215 : void visitInitElem(LInitElem* lir);
216 : void visitInitElemGetterSetter(LInitElemGetterSetter* lir);
217 : void visitMutateProto(LMutateProto* lir);
218 : void visitInitProp(LInitProp* lir);
219 : void visitInitPropGetterSetter(LInitPropGetterSetter* lir);
220 : void visitCreateThis(LCreateThis* lir);
221 : void visitCreateThisWithProto(LCreateThisWithProto* lir);
222 : void visitCreateThisWithTemplate(LCreateThisWithTemplate* lir);
223 : void visitCreateArgumentsObject(LCreateArgumentsObject* lir);
224 : void visitGetArgumentsObjectArg(LGetArgumentsObjectArg* lir);
225 : void visitSetArgumentsObjectArg(LSetArgumentsObjectArg* lir);
226 : void visitReturnFromCtor(LReturnFromCtor* lir);
227 : void visitComputeThis(LComputeThis* lir);
228 : void visitArrayLength(LArrayLength* lir);
229 : void visitSetArrayLength(LSetArrayLength* lir);
230 : void visitGetNextEntryForIterator(LGetNextEntryForIterator* lir);
231 : void visitTypedArrayLength(LTypedArrayLength* lir);
232 : void visitTypedArrayElements(LTypedArrayElements* lir);
233 : void visitSetDisjointTypedElements(LSetDisjointTypedElements* lir);
234 : void visitTypedObjectElements(LTypedObjectElements* lir);
235 : void visitSetTypedObjectOffset(LSetTypedObjectOffset* lir);
236 : void visitTypedObjectDescr(LTypedObjectDescr* ins);
237 : void visitStringLength(LStringLength* lir);
238 : void visitSubstr(LSubstr* lir);
239 : void visitInitializedLength(LInitializedLength* lir);
240 : void visitSetInitializedLength(LSetInitializedLength* lir);
241 : void visitUnboxedArrayLength(LUnboxedArrayLength* lir);
242 : void visitUnboxedArrayInitializedLength(LUnboxedArrayInitializedLength* lir);
243 : void visitIncrementUnboxedArrayInitializedLength(LIncrementUnboxedArrayInitializedLength* lir);
244 : void visitSetUnboxedArrayInitializedLength(LSetUnboxedArrayInitializedLength* lir);
245 : void visitNotO(LNotO* ins);
246 : void visitNotV(LNotV* ins);
247 : void visitBoundsCheck(LBoundsCheck* lir);
248 : void visitBoundsCheckRange(LBoundsCheckRange* lir);
249 : void visitBoundsCheckLower(LBoundsCheckLower* lir);
250 : void visitLoadFixedSlotV(LLoadFixedSlotV* ins);
251 : void visitLoadFixedSlotAndUnbox(LLoadFixedSlotAndUnbox* lir);
252 : void visitLoadFixedSlotT(LLoadFixedSlotT* ins);
253 : void visitStoreFixedSlotV(LStoreFixedSlotV* ins);
254 : void visitStoreFixedSlotT(LStoreFixedSlotT* ins);
255 : void emitGetPropertyPolymorphic(LInstruction* lir, Register obj,
256 : Register scratch, const TypedOrValueRegister& output);
257 : void visitGetPropertyPolymorphicV(LGetPropertyPolymorphicV* ins);
258 : void visitGetPropertyPolymorphicT(LGetPropertyPolymorphicT* ins);
259 : void emitSetPropertyPolymorphic(LInstruction* lir, Register obj,
260 : Register scratch, const ConstantOrRegister& value);
261 : void visitSetPropertyPolymorphicV(LSetPropertyPolymorphicV* ins);
262 : void visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins);
263 : void visitAbsI(LAbsI* lir);
264 : void visitAtan2D(LAtan2D* lir);
265 : void visitHypot(LHypot* lir);
266 : void visitPowI(LPowI* lir);
267 : void visitPowD(LPowD* lir);
268 : void visitPowV(LPowV* lir);
269 : void visitMathFunctionD(LMathFunctionD* ins);
270 : void visitMathFunctionF(LMathFunctionF* ins);
271 : void visitModD(LModD* ins);
272 : void visitMinMaxI(LMinMaxI* lir);
273 : void visitBinaryV(LBinaryV* lir);
274 : void emitCompareS(LInstruction* lir, JSOp op, Register left, Register right, Register output);
275 : void visitCompareS(LCompareS* lir);
276 : void visitCompareStrictS(LCompareStrictS* lir);
277 : void visitCompareVM(LCompareVM* lir);
278 : void visitIsNullOrLikeUndefinedV(LIsNullOrLikeUndefinedV* lir);
279 : void visitIsNullOrLikeUndefinedT(LIsNullOrLikeUndefinedT* lir);
280 : void visitIsNullOrLikeUndefinedAndBranchV(LIsNullOrLikeUndefinedAndBranchV* lir);
281 : void visitIsNullOrLikeUndefinedAndBranchT(LIsNullOrLikeUndefinedAndBranchT* lir);
282 : void emitConcat(LInstruction* lir, Register lhs, Register rhs, Register output);
283 : void visitConcat(LConcat* lir);
284 : void visitCharCodeAt(LCharCodeAt* lir);
285 : void visitFromCharCode(LFromCharCode* lir);
286 : void visitFromCodePoint(LFromCodePoint* lir);
287 : void visitSinCos(LSinCos *lir);
288 : void visitStringSplit(LStringSplit* lir);
289 : void visitFunctionEnvironment(LFunctionEnvironment* lir);
290 : void visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir);
291 : void visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject* lir);
292 : void visitCallGetProperty(LCallGetProperty* lir);
293 : void visitCallGetElement(LCallGetElement* lir);
294 : void visitCallSetElement(LCallSetElement* lir);
295 : void visitCallInitElementArray(LCallInitElementArray* lir);
296 : void visitThrow(LThrow* lir);
297 : void visitTypeOfV(LTypeOfV* lir);
298 : void visitOutOfLineTypeOfV(OutOfLineTypeOfV* ool);
299 : void visitToAsync(LToAsync* lir);
300 : void visitToAsyncGen(LToAsyncGen* lir);
301 : void visitToAsyncIter(LToAsyncIter* lir);
302 : void visitToIdV(LToIdV* lir);
303 : template<typename T> void emitLoadElementT(LLoadElementT* lir, const T& source);
304 : void visitLoadElementT(LLoadElementT* lir);
305 : void visitLoadElementV(LLoadElementV* load);
306 : void visitLoadElementHole(LLoadElementHole* lir);
307 : void visitLoadUnboxedPointerV(LLoadUnboxedPointerV* lir);
308 : void visitLoadUnboxedPointerT(LLoadUnboxedPointerT* lir);
309 : void visitUnboxObjectOrNull(LUnboxObjectOrNull* lir);
310 : void visitStoreElementT(LStoreElementT* lir);
311 : void visitStoreElementV(LStoreElementV* lir);
312 : template <typename T> void emitStoreElementHoleT(T* lir);
313 : template <typename T> void emitStoreElementHoleV(T* lir);
314 : void visitStoreElementHoleT(LStoreElementHoleT* lir);
315 : void visitStoreElementHoleV(LStoreElementHoleV* lir);
316 : void visitFallibleStoreElementV(LFallibleStoreElementV* lir);
317 : void visitFallibleStoreElementT(LFallibleStoreElementT* lir);
318 : void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir);
319 : void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir);
320 : void emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, Register obj,
321 : Register elementsTemp, Register lengthTemp, TypedOrValueRegister out);
322 : void visitArrayPopShiftV(LArrayPopShiftV* lir);
323 : void visitArrayPopShiftT(LArrayPopShiftT* lir);
324 : void emitArrayPush(LInstruction* lir, const MArrayPush* mir, Register obj,
325 : const ConstantOrRegister& value, Register elementsTemp, Register length);
326 : void visitArrayPushV(LArrayPushV* lir);
327 : void visitArrayPushT(LArrayPushT* lir);
328 : void visitArraySlice(LArraySlice* lir);
329 : void visitArrayJoin(LArrayJoin* lir);
330 : void visitLoadUnboxedScalar(LLoadUnboxedScalar* lir);
331 : void visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir);
332 : void visitStoreUnboxedScalar(LStoreUnboxedScalar* lir);
333 : void visitStoreTypedArrayElementHole(LStoreTypedArrayElementHole* lir);
334 : void visitAtomicIsLockFree(LAtomicIsLockFree* lir);
335 : void visitGuardSharedTypedArray(LGuardSharedTypedArray* lir);
336 : void visitClampIToUint8(LClampIToUint8* lir);
337 : void visitClampDToUint8(LClampDToUint8* lir);
338 : void visitClampVToUint8(LClampVToUint8* lir);
339 : void visitCallIteratorStartV(LCallIteratorStartV* lir);
340 : void visitCallIteratorStartO(LCallIteratorStartO* lir);
341 : void visitIteratorStartO(LIteratorStartO* lir);
342 : void visitIteratorMore(LIteratorMore* lir);
343 : void visitIsNoIterAndBranch(LIsNoIterAndBranch* lir);
344 : void visitIteratorEnd(LIteratorEnd* lir);
345 : void visitArgumentsLength(LArgumentsLength* lir);
346 : void visitGetFrameArgument(LGetFrameArgument* lir);
347 : void visitSetFrameArgumentT(LSetFrameArgumentT* lir);
348 : void visitSetFrameArgumentC(LSetFrameArgumentC* lir);
349 : void visitSetFrameArgumentV(LSetFrameArgumentV* lir);
350 : void visitRunOncePrologue(LRunOncePrologue* lir);
351 : void emitRest(LInstruction* lir, Register array, Register numActuals,
352 : Register temp0, Register temp1, unsigned numFormals,
353 : JSObject* templateObject, bool saveAndRestore, Register resultreg);
354 : void visitRest(LRest* lir);
355 : void visitCallSetProperty(LCallSetProperty* ins);
356 : void visitCallDeleteProperty(LCallDeleteProperty* lir);
357 : void visitCallDeleteElement(LCallDeleteElement* lir);
358 : void visitBitNotV(LBitNotV* lir);
359 : void visitBitOpV(LBitOpV* lir);
360 : void emitInstanceOf(LInstruction* ins, JSObject* prototypeObject);
361 : void visitInCache(LInCache* ins);
362 : void visitInArray(LInArray* ins);
363 : void visitInstanceOfO(LInstanceOfO* ins);
364 : void visitInstanceOfV(LInstanceOfV* ins);
365 : void visitCallInstanceOf(LCallInstanceOf* ins);
366 : void visitGetDOMProperty(LGetDOMProperty* lir);
367 : void visitGetDOMMemberV(LGetDOMMemberV* lir);
368 : void visitGetDOMMemberT(LGetDOMMemberT* lir);
369 : void visitSetDOMProperty(LSetDOMProperty* lir);
370 : void visitCallDOMNative(LCallDOMNative* lir);
371 : void visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir);
372 : void visitCallBindVar(LCallBindVar* lir);
373 : enum CallableOrConstructor {
374 : Callable,
375 : Constructor
376 : };
377 : template <CallableOrConstructor mode>
378 : void emitIsCallableOrConstructor(Register object, Register output, Label* failure);
379 : void visitIsCallable(LIsCallable* lir);
380 : void visitOutOfLineIsCallable(OutOfLineIsCallable* ool);
381 : void visitIsConstructor(LIsConstructor* lir);
382 : void visitOutOfLineIsConstructor(OutOfLineIsConstructor* ool);
383 : void visitIsArrayO(LIsArrayO* lir);
384 : void visitIsArrayV(LIsArrayV* lir);
385 : void visitIsObject(LIsObject* lir);
386 : void visitIsObjectAndBranch(LIsObjectAndBranch* lir);
387 : void visitHasClass(LHasClass* lir);
388 : void visitWasmParameter(LWasmParameter* lir);
389 : void visitWasmParameterI64(LWasmParameterI64* lir);
390 : void visitWasmReturn(LWasmReturn* ret);
391 : void visitWasmReturnI64(LWasmReturnI64* ret);
392 : void visitWasmReturnVoid(LWasmReturnVoid* ret);
393 : void visitLexicalCheck(LLexicalCheck* ins);
394 : void visitThrowRuntimeLexicalError(LThrowRuntimeLexicalError* ins);
395 : void visitGlobalNameConflictsCheck(LGlobalNameConflictsCheck* ins);
396 : void visitDebugger(LDebugger* ins);
397 : void visitNewTarget(LNewTarget* ins);
398 : void visitArrowNewTarget(LArrowNewTarget* ins);
399 : void visitCheckReturn(LCheckReturn* ins);
400 : void visitCheckIsObj(LCheckIsObj* ins);
401 : void visitCheckIsCallable(LCheckIsCallable* ins);
402 : void visitCheckObjCoercible(LCheckObjCoercible* ins);
403 : void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins);
404 : void visitNaNToZero(LNaNToZero* ins);
405 : void visitOutOfLineNaNToZero(OutOfLineNaNToZero* ool);
406 : void visitFinishBoundFunctionInit(LFinishBoundFunctionInit* lir);
407 :
408 : void visitCheckOverRecursed(LCheckOverRecursed* lir);
409 : void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool);
410 :
411 : void visitUnboxFloatingPoint(LUnboxFloatingPoint* lir);
412 : void visitOutOfLineUnboxFloatingPoint(OutOfLineUnboxFloatingPoint* ool);
413 : void visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool);
414 :
415 : void loadJSScriptForBlock(MBasicBlock* block, Register reg);
416 : void loadOutermostJSScript(Register reg);
417 :
418 : void visitOutOfLineICFallback(OutOfLineICFallback* ool);
419 :
420 : void visitGetPropertyCacheV(LGetPropertyCacheV* ins);
421 : void visitGetPropertyCacheT(LGetPropertyCacheT* ins);
422 : void visitBindNameCache(LBindNameCache* ins);
423 : void visitCallSetProperty(LInstruction* ins);
424 : void visitSetPropertyCache(LSetPropertyCache* ins);
425 : void visitGetNameCache(LGetNameCache* ins);
426 : void visitHasOwnCache(LHasOwnCache* ins);
427 :
428 : void visitAssertRangeI(LAssertRangeI* ins);
429 : void visitAssertRangeD(LAssertRangeD* ins);
430 : void visitAssertRangeF(LAssertRangeF* ins);
431 : void visitAssertRangeV(LAssertRangeV* ins);
432 :
433 : void visitAssertResultV(LAssertResultV* ins);
434 : void visitAssertResultT(LAssertResultT* ins);
435 : void emitAssertResultV(const ValueOperand output, const TemporaryTypeSet* typeset);
436 : void emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset);
437 :
438 : void visitInterruptCheck(LInterruptCheck* lir);
439 : void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins);
440 : void visitWasmTrap(LWasmTrap* lir);
441 : void visitWasmLoadTls(LWasmLoadTls* ins);
442 : void visitWasmBoundsCheck(LWasmBoundsCheck* ins);
443 : void visitRecompileCheck(LRecompileCheck* ins);
444 : void visitRotate(LRotate* ins);
445 :
446 : void visitRandom(LRandom* ins);
447 : void visitSignExtend(LSignExtend* ins);
448 :
449 : #ifdef DEBUG
450 : void emitDebugForceBailing(LInstruction* lir);
451 : #endif
452 :
453 5 : IonScriptCounts* extractScriptCounts() {
454 5 : IonScriptCounts* counts = scriptCounts_;
455 5 : scriptCounts_ = nullptr; // prevent delete in dtor
456 5 : return counts;
457 : }
458 :
459 : private:
460 : void addGetPropertyCache(LInstruction* ins, LiveRegisterSet liveRegs,
461 : TypedOrValueRegister value, const ConstantOrRegister& id,
462 : TypedOrValueRegister output, Register maybeTemp, bool monitoredResult,
463 : bool allowDoubleResult, jsbytecode* profilerLeavePc);
464 : void addSetPropertyCache(LInstruction* ins, LiveRegisterSet liveRegs, Register objReg,
465 : Register temp, FloatRegister tempDouble,
466 : FloatRegister tempF32, const ConstantOrRegister& id,
467 : const ConstantOrRegister& value,
468 : bool strict, bool needsPostBarrier, bool needsTypeBarrier,
469 : bool guardHoles, jsbytecode* profilerLeavePc);
470 :
471 : MOZ_MUST_USE bool generateBranchV(const ValueOperand& value, Label* ifTrue, Label* ifFalse,
472 : FloatRegister fr);
473 :
474 : void emitLambdaInit(Register resultReg, Register envChainReg,
475 : const LambdaFunctionInfo& info);
476 :
477 : void emitFilterArgumentsOrEval(LInstruction* lir, Register string, Register temp1,
478 : Register temp2);
479 :
480 : template <class IteratorObject, class OrderedHashTable>
481 : void emitGetNextEntryForIterator(LGetNextEntryForIterator* lir);
482 :
483 : template <class OrderedHashTable>
484 : void emitLoadIteratorValues(Register result, Register temp, Register front);
485 :
486 : IonScriptCounts* maybeCreateScriptCounts();
487 :
488 : // This function behaves like testValueTruthy with the exception that it can
489 : // choose to let control flow fall through when the object is truthy, as
490 : // an optimization. Use testValueTruthy when it's required to branch to one
491 : // of the two labels.
492 : void testValueTruthyKernel(const ValueOperand& value,
493 : const LDefinition* scratch1, const LDefinition* scratch2,
494 : FloatRegister fr,
495 : Label* ifTruthy, Label* ifFalsy,
496 : OutOfLineTestObject* ool,
497 : MDefinition* valueMIR);
498 :
499 : // Test whether value is truthy or not and jump to the corresponding label.
500 : // If the value can be an object that emulates |undefined|, |ool| must be
501 : // non-null; otherwise it may be null (and the scratch definitions should
502 : // be bogus), in which case an object encountered here will always be
503 : // truthy.
504 : void testValueTruthy(const ValueOperand& value,
505 : const LDefinition* scratch1, const LDefinition* scratch2,
506 : FloatRegister fr,
507 : Label* ifTruthy, Label* ifFalsy,
508 : OutOfLineTestObject* ool,
509 : MDefinition* valueMIR);
510 :
511 : // This function behaves like testObjectEmulatesUndefined with the exception
512 : // that it can choose to let control flow fall through when the object
513 : // doesn't emulate undefined, as an optimization. Use the regular
514 : // testObjectEmulatesUndefined when it's required to branch to one of the
515 : // two labels.
516 : void testObjectEmulatesUndefinedKernel(Register objreg,
517 : Label* ifEmulatesUndefined,
518 : Label* ifDoesntEmulateUndefined,
519 : Register scratch, OutOfLineTestObject* ool);
520 :
521 : // Test whether an object emulates |undefined|. If it does, jump to
522 : // |ifEmulatesUndefined|; the caller is responsible for binding this label.
523 : // If it doesn't, fall through; the label |ifDoesntEmulateUndefined| (which
524 : // must be initially unbound) will be bound at this point.
525 : void branchTestObjectEmulatesUndefined(Register objreg,
526 : Label* ifEmulatesUndefined,
527 : Label* ifDoesntEmulateUndefined,
528 : Register scratch, OutOfLineTestObject* ool);
529 :
530 : // Test whether an object emulates |undefined|, and jump to the
531 : // corresponding label.
532 : //
533 : // This method should be used when subsequent code can't be laid out in a
534 : // straight line; if it can, branchTest* should be used instead.
535 : void testObjectEmulatesUndefined(Register objreg,
536 : Label* ifEmulatesUndefined,
537 : Label* ifDoesntEmulateUndefined,
538 : Register scratch, OutOfLineTestObject* ool);
539 :
540 : // Branch to target unless obj has an emptyObjectElements or emptyObjectElementsShared
541 : // elements pointer.
542 : void branchIfNotEmptyObjectElements(Register obj, Label* target);
543 :
544 : void emitStoreElementTyped(const LAllocation* value, MIRType valueType, MIRType elementType,
545 : Register elements, const LAllocation* index,
546 : int32_t offsetAdjustment);
547 :
548 : // Bailout if an element about to be written to is a hole.
549 : void emitStoreHoleCheck(Register elements, const LAllocation* index, int32_t offsetAdjustment,
550 : LSnapshot* snapshot);
551 :
552 : void emitAssertRangeI(const Range* r, Register input);
553 : void emitAssertRangeD(const Range* r, FloatRegister input, FloatRegister temp);
554 :
555 : void maybeEmitGlobalBarrierCheck(const LAllocation* maybeGlobal, OutOfLineCode* ool);
556 :
557 : Vector<CodeOffset, 0, JitAllocPolicy> ionScriptLabels_;
558 :
559 : struct SharedStub {
560 : ICStub::Kind kind;
561 : IonICEntry entry;
562 : CodeOffset label;
563 :
564 0 : SharedStub(ICStub::Kind kind, IonICEntry entry, CodeOffset label)
565 0 : : kind(kind), entry(entry), label(label)
566 0 : {}
567 : };
568 :
569 : Vector<SharedStub, 0, SystemAllocPolicy> sharedStubs_;
570 :
571 : void branchIfInvalidated(Register temp, Label* invalidated);
572 :
573 : #ifdef DEBUG
574 : void emitDebugResultChecks(LInstruction* ins);
575 : void emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir);
576 : void emitValueResultChecks(LInstruction* lir, MDefinition* mir);
577 : #endif
578 :
579 : // Script counts created during code generation.
580 : IonScriptCounts* scriptCounts_;
581 :
582 : #if defined(JS_ION_PERF)
583 : PerfSpewer perfSpewer_;
584 : #endif
585 :
586 : // This integer is a bit mask of all SimdTypeDescr::Type indexes. When a
587 : // MSimdBox instruction is encoded, it might have either been created by
588 : // IonBuilder, or by the Eager Simd Unbox phase.
589 : //
590 : // As the template objects are weak references, the JitCompartment is using
591 : // Read Barriers, but such barrier cannot be used during the compilation. To
592 : // work around this issue, the barriers are captured during
593 : // CodeGenerator::link.
594 : //
595 : // Instead of saving the pointers, we just save the index of the Read
596 : // Barriered objects in a bit mask.
597 : uint32_t simdRefreshTemplatesDuringLink_;
598 :
599 : void registerSimdTemplate(SimdType simdType);
600 : void captureSimdTemplate(JSContext* cx);
601 : };
602 :
603 : } // namespace jit
604 : } // namespace js
605 :
606 : #endif /* jit_CodeGenerator_h */
|