1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
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_CacheIRGenerator_h
8 #define jit_CacheIRGenerator_h
9 
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Attributes.h"
12 
13 #include <stdint.h>
14 
15 #include "jstypes.h"
16 #include "NamespaceImports.h"
17 
18 #include "gc/Rooting.h"
19 #include "jit/CacheIR.h"
20 #include "jit/CacheIRWriter.h"
21 #include "jit/ICState.h"
22 #include "js/Id.h"
23 #include "js/RootingAPI.h"
24 #include "js/ScalarType.h"
25 #include "js/TypeDecls.h"
26 #include "js/Value.h"
27 #include "js/ValueArray.h"
28 #include "vm/Opcodes.h"
29 
30 class JSFunction;
31 
32 namespace JS {
33 struct XrayJitInfo;
34 }
35 
36 namespace js {
37 
38 class NativeObject;
39 class PropertyResult;
40 class ProxyObject;
41 enum class UnaryMathFunction : uint8_t;
42 
43 namespace jit {
44 
45 class BaselineFrame;
46 class Label;
47 class MacroAssembler;
48 struct Register;
49 enum class InlinableNative : uint16_t;
50 
51 // Some ops refer to shapes that might be in other zones. Instead of putting
52 // cross-zone pointers in the caches themselves (which would complicate tracing
53 // enormously), these ops instead contain wrappers for objects in the target
54 // zone, which refer to the actual shape via a reserved slot.
55 void LoadShapeWrapperContents(MacroAssembler& masm, Register obj, Register dst,
56                               Label* failure);
57 
58 class MOZ_RAII IRGenerator {
59  protected:
60   CacheIRWriter writer;
61   JSContext* cx_;
62   HandleScript script_;
63   jsbytecode* pc_;
64   CacheKind cacheKind_;
65   ICState::Mode mode_;
66   bool isFirstStub_;
67 
68   IRGenerator(const IRGenerator&) = delete;
69   IRGenerator& operator=(const IRGenerator&) = delete;
70 
71   bool maybeGuardInt32Index(const Value& index, ValOperandId indexId,
72                             uint32_t* int32Index, Int32OperandId* int32IndexId);
73 
74   IntPtrOperandId guardToIntPtrIndex(const Value& index, ValOperandId indexId,
75                                      bool supportOOB);
76 
77   ObjOperandId guardDOMProxyExpandoObjectAndShape(ProxyObject* obj,
78                                                   ObjOperandId objId,
79                                                   const Value& expandoVal,
80                                                   NativeObject* expandoObj);
81 
82   void emitIdGuard(ValOperandId valId, const Value& idVal, jsid id);
83 
84   OperandId emitNumericGuard(ValOperandId valId, Scalar::Type type);
85 
86   StringOperandId emitToStringGuard(ValOperandId id, const Value& v);
87 
88   friend class CacheIRSpewer;
89 
90  public:
91   explicit IRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
92                        CacheKind cacheKind, ICState state);
93 
writerRef()94   const CacheIRWriter& writerRef() const { return writer; }
cacheKind()95   CacheKind cacheKind() const { return cacheKind_; }
96 
97   static constexpr char* NotAttached = nullptr;
98 };
99 
100 // GetPropIRGenerator generates CacheIR for a GetProp IC.
101 class MOZ_RAII GetPropIRGenerator : public IRGenerator {
102   HandleValue val_;
103   HandleValue idVal_;
104 
105   AttachDecision tryAttachNative(HandleObject obj, ObjOperandId objId,
106                                  HandleId id, ValOperandId receiverId);
107   AttachDecision tryAttachObjectLength(HandleObject obj, ObjOperandId objId,
108                                        HandleId id);
109   AttachDecision tryAttachTypedArray(HandleObject obj, ObjOperandId objId,
110                                      HandleId id);
111   AttachDecision tryAttachDataView(HandleObject obj, ObjOperandId objId,
112                                    HandleId id);
113   AttachDecision tryAttachArrayBufferMaybeShared(HandleObject obj,
114                                                  ObjOperandId objId,
115                                                  HandleId id);
116   AttachDecision tryAttachRegExp(HandleObject obj, ObjOperandId objId,
117                                  HandleId id);
118   AttachDecision tryAttachModuleNamespace(HandleObject obj, ObjOperandId objId,
119                                           HandleId id);
120   AttachDecision tryAttachWindowProxy(HandleObject obj, ObjOperandId objId,
121                                       HandleId id);
122   AttachDecision tryAttachCrossCompartmentWrapper(HandleObject obj,
123                                                   ObjOperandId objId,
124                                                   HandleId id);
125   AttachDecision tryAttachXrayCrossCompartmentWrapper(HandleObject obj,
126                                                       ObjOperandId objId,
127                                                       HandleId id,
128                                                       ValOperandId receiverId);
129   AttachDecision tryAttachFunction(HandleObject obj, ObjOperandId objId,
130                                    HandleId id);
131   AttachDecision tryAttachArgumentsObjectIterator(HandleObject obj,
132                                                   ObjOperandId objId,
133                                                   HandleId id);
134 
135   AttachDecision tryAttachGenericProxy(Handle<ProxyObject*> obj,
136                                        ObjOperandId objId, HandleId id,
137                                        bool handleDOMProxies);
138   AttachDecision tryAttachDOMProxyExpando(Handle<ProxyObject*> obj,
139                                           ObjOperandId objId, HandleId id,
140                                           ValOperandId receiverId);
141   AttachDecision tryAttachDOMProxyShadowed(Handle<ProxyObject*> obj,
142                                            ObjOperandId objId, HandleId id);
143   AttachDecision tryAttachDOMProxyUnshadowed(Handle<ProxyObject*> obj,
144                                              ObjOperandId objId, HandleId id,
145                                              ValOperandId receiverId);
146   AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId,
147                                 HandleId id, ValOperandId receiverId);
148 
149   AttachDecision tryAttachPrimitive(ValOperandId valId, HandleId id);
150   AttachDecision tryAttachStringChar(ValOperandId valId, ValOperandId indexId);
151   AttachDecision tryAttachStringLength(ValOperandId valId, HandleId id);
152 
153   AttachDecision tryAttachArgumentsObjectArg(HandleObject obj,
154                                              ObjOperandId objId, uint32_t index,
155                                              Int32OperandId indexId);
156   AttachDecision tryAttachArgumentsObjectArgHole(HandleObject obj,
157                                                  ObjOperandId objId,
158                                                  uint32_t index,
159                                                  Int32OperandId indexId);
160   AttachDecision tryAttachArgumentsObjectCallee(HandleObject obj,
161                                                 ObjOperandId objId,
162                                                 HandleId id);
163 
164   AttachDecision tryAttachDenseElement(HandleObject obj, ObjOperandId objId,
165                                        uint32_t index, Int32OperandId indexId);
166   AttachDecision tryAttachDenseElementHole(HandleObject obj, ObjOperandId objId,
167                                            uint32_t index,
168                                            Int32OperandId indexId);
169   AttachDecision tryAttachSparseElement(HandleObject obj, ObjOperandId objId,
170                                         uint32_t index, Int32OperandId indexId);
171   AttachDecision tryAttachTypedArrayElement(HandleObject obj,
172                                             ObjOperandId objId);
173 
174   AttachDecision tryAttachGenericElement(HandleObject obj, ObjOperandId objId,
175                                          uint32_t index,
176                                          Int32OperandId indexId);
177 
178   AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId);
179 
180   void attachMegamorphicNativeSlot(ObjOperandId objId, jsid id);
181 
getElemKeyValueId()182   ValOperandId getElemKeyValueId() const {
183     MOZ_ASSERT(cacheKind_ == CacheKind::GetElem ||
184                cacheKind_ == CacheKind::GetElemSuper);
185     return ValOperandId(1);
186   }
187 
getSuperReceiverValueId()188   ValOperandId getSuperReceiverValueId() const {
189     if (cacheKind_ == CacheKind::GetPropSuper) {
190       return ValOperandId(1);
191     }
192 
193     MOZ_ASSERT(cacheKind_ == CacheKind::GetElemSuper);
194     return ValOperandId(2);
195   }
196 
isSuper()197   bool isSuper() const {
198     return (cacheKind_ == CacheKind::GetPropSuper ||
199             cacheKind_ == CacheKind::GetElemSuper);
200   }
201 
202   // If this is a GetElem cache, emit instructions to guard the incoming Value
203   // matches |id|.
204   void maybeEmitIdGuard(jsid id);
205 
206   void trackAttached(const char* name);
207 
208  public:
209   GetPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
210                      ICState state, CacheKind cacheKind, HandleValue val,
211                      HandleValue idVal);
212 
213   AttachDecision tryAttachStub();
214 };
215 
216 // GetNameIRGenerator generates CacheIR for a GetName IC.
217 class MOZ_RAII GetNameIRGenerator : public IRGenerator {
218   HandleObject env_;
219   HandlePropertyName name_;
220 
221   AttachDecision tryAttachGlobalNameValue(ObjOperandId objId, HandleId id);
222   AttachDecision tryAttachGlobalNameGetter(ObjOperandId objId, HandleId id);
223   AttachDecision tryAttachEnvironmentName(ObjOperandId objId, HandleId id);
224 
225   void trackAttached(const char* name);
226 
227  public:
228   GetNameIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
229                      ICState state, HandleObject env, HandlePropertyName name);
230 
231   AttachDecision tryAttachStub();
232 };
233 
234 // BindNameIRGenerator generates CacheIR for a BindName IC.
235 class MOZ_RAII BindNameIRGenerator : public IRGenerator {
236   HandleObject env_;
237   HandlePropertyName name_;
238 
239   AttachDecision tryAttachGlobalName(ObjOperandId objId, HandleId id);
240   AttachDecision tryAttachEnvironmentName(ObjOperandId objId, HandleId id);
241 
242   void trackAttached(const char* name);
243 
244  public:
245   BindNameIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
246                       ICState state, HandleObject env, HandlePropertyName name);
247 
248   AttachDecision tryAttachStub();
249 };
250 
251 // SetPropIRGenerator generates CacheIR for a SetProp IC.
252 class MOZ_RAII SetPropIRGenerator : public IRGenerator {
253   HandleValue lhsVal_;
254   HandleValue idVal_;
255   HandleValue rhsVal_;
256 
257  public:
258   enum class DeferType { None, AddSlot };
259 
260  private:
261   DeferType deferType_ = DeferType::None;
262 
setElemKeyValueId()263   ValOperandId setElemKeyValueId() const {
264     MOZ_ASSERT(cacheKind_ == CacheKind::SetElem);
265     return ValOperandId(1);
266   }
267 
rhsValueId()268   ValOperandId rhsValueId() const {
269     if (cacheKind_ == CacheKind::SetProp) {
270       return ValOperandId(1);
271     }
272     MOZ_ASSERT(cacheKind_ == CacheKind::SetElem);
273     return ValOperandId(2);
274   }
275 
276   // If this is a SetElem cache, emit instructions to guard the incoming Value
277   // matches |id|.
278   void maybeEmitIdGuard(jsid id);
279 
280   AttachDecision tryAttachNativeSetSlot(HandleObject obj, ObjOperandId objId,
281                                         HandleId id, ValOperandId rhsId);
282   AttachDecision tryAttachSetter(HandleObject obj, ObjOperandId objId,
283                                  HandleId id, ValOperandId rhsId);
284   AttachDecision tryAttachSetArrayLength(HandleObject obj, ObjOperandId objId,
285                                          HandleId id, ValOperandId rhsId);
286   AttachDecision tryAttachWindowProxy(HandleObject obj, ObjOperandId objId,
287                                       HandleId id, ValOperandId rhsId);
288 
289   AttachDecision tryAttachSetDenseElement(HandleObject obj, ObjOperandId objId,
290                                           uint32_t index,
291                                           Int32OperandId indexId,
292                                           ValOperandId rhsId);
293   AttachDecision tryAttachSetTypedArrayElement(HandleObject obj,
294                                                ObjOperandId objId,
295                                                ValOperandId rhsId);
296 
297   AttachDecision tryAttachSetDenseElementHole(HandleObject obj,
298                                               ObjOperandId objId,
299                                               uint32_t index,
300                                               Int32OperandId indexId,
301                                               ValOperandId rhsId);
302 
303   AttachDecision tryAttachAddOrUpdateSparseElement(HandleObject obj,
304                                                    ObjOperandId objId,
305                                                    uint32_t index,
306                                                    Int32OperandId indexId,
307                                                    ValOperandId rhsId);
308 
309   AttachDecision tryAttachGenericProxy(Handle<ProxyObject*> obj,
310                                        ObjOperandId objId, HandleId id,
311                                        ValOperandId rhsId,
312                                        bool handleDOMProxies);
313   AttachDecision tryAttachDOMProxyShadowed(Handle<ProxyObject*> obj,
314                                            ObjOperandId objId, HandleId id,
315                                            ValOperandId rhsId);
316   AttachDecision tryAttachDOMProxyUnshadowed(Handle<ProxyObject*> obj,
317                                              ObjOperandId objId, HandleId id,
318                                              ValOperandId rhsId);
319   AttachDecision tryAttachDOMProxyExpando(Handle<ProxyObject*> obj,
320                                           ObjOperandId objId, HandleId id,
321                                           ValOperandId rhsId);
322   AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId,
323                                 HandleId id, ValOperandId rhsId);
324   AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
325                                        ValOperandId rhsId);
326   AttachDecision tryAttachMegamorphicSetElement(HandleObject obj,
327                                                 ObjOperandId objId,
328                                                 ValOperandId rhsId);
329 
330   bool canAttachAddSlotStub(HandleObject obj, HandleId id);
331 
332  public:
333   SetPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
334                      CacheKind cacheKind, ICState state, HandleValue lhsVal,
335                      HandleValue idVal, HandleValue rhsVal);
336 
337   AttachDecision tryAttachStub();
338   AttachDecision tryAttachAddSlotStub(HandleShape oldShape);
339   void trackAttached(const char* name);
340 
deferType()341   DeferType deferType() const { return deferType_; }
342 };
343 
344 // HasPropIRGenerator generates CacheIR for a HasProp IC. Used for
345 // CacheKind::In / CacheKind::HasOwn.
346 class MOZ_RAII HasPropIRGenerator : public IRGenerator {
347   HandleValue val_;
348   HandleValue idVal_;
349 
350   AttachDecision tryAttachDense(HandleObject obj, ObjOperandId objId,
351                                 uint32_t index, Int32OperandId indexId);
352   AttachDecision tryAttachDenseHole(HandleObject obj, ObjOperandId objId,
353                                     uint32_t index, Int32OperandId indexId);
354   AttachDecision tryAttachTypedArray(HandleObject obj, ObjOperandId objId,
355                                      ValOperandId keyId);
356   AttachDecision tryAttachSparse(HandleObject obj, ObjOperandId objId,
357                                  Int32OperandId indexId);
358   AttachDecision tryAttachArgumentsObjectArg(HandleObject obj,
359                                              ObjOperandId objId,
360                                              Int32OperandId indexId);
361   AttachDecision tryAttachNamedProp(HandleObject obj, ObjOperandId objId,
362                                     HandleId key, ValOperandId keyId);
363   AttachDecision tryAttachMegamorphic(ObjOperandId objId, ValOperandId keyId);
364   AttachDecision tryAttachNative(NativeObject* obj, ObjOperandId objId,
365                                  jsid key, ValOperandId keyId,
366                                  PropertyResult prop, NativeObject* holder);
367   AttachDecision tryAttachSlotDoesNotExist(NativeObject* obj,
368                                            ObjOperandId objId, jsid key,
369                                            ValOperandId keyId);
370   AttachDecision tryAttachDoesNotExist(HandleObject obj, ObjOperandId objId,
371                                        HandleId key, ValOperandId keyId);
372   AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
373                                        ValOperandId keyId);
374 
375   void trackAttached(const char* name);
376 
377  public:
378   // NOTE: Argument order is PROPERTY, OBJECT
379   HasPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
380                      ICState state, CacheKind cacheKind, HandleValue idVal,
381                      HandleValue val);
382 
383   AttachDecision tryAttachStub();
384 };
385 
386 class MOZ_RAII CheckPrivateFieldIRGenerator : public IRGenerator {
387   HandleValue val_;
388   HandleValue idVal_;
389 
390   AttachDecision tryAttachNative(JSObject* obj, ObjOperandId objId, jsid key,
391                                  ValOperandId keyId, bool hasOwn);
392 
393   void trackAttached(const char* name);
394 
395  public:
396   CheckPrivateFieldIRGenerator(JSContext* cx, HandleScript script,
397                                jsbytecode* pc, ICState state,
398                                CacheKind cacheKind, HandleValue idVal,
399                                HandleValue val);
400   AttachDecision tryAttachStub();
401 };
402 
403 class MOZ_RAII InstanceOfIRGenerator : public IRGenerator {
404   HandleValue lhsVal_;
405   HandleObject rhsObj_;
406 
407   void trackAttached(const char* name);
408 
409  public:
410   InstanceOfIRGenerator(JSContext*, HandleScript, jsbytecode*, ICState,
411                         HandleValue, HandleObject);
412 
413   AttachDecision tryAttachStub();
414 };
415 
416 class MOZ_RAII TypeOfIRGenerator : public IRGenerator {
417   HandleValue val_;
418 
419   AttachDecision tryAttachPrimitive(ValOperandId valId);
420   AttachDecision tryAttachObject(ValOperandId valId);
421   void trackAttached(const char* name);
422 
423  public:
424   TypeOfIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState state,
425                     HandleValue value);
426 
427   AttachDecision tryAttachStub();
428 };
429 
430 class MOZ_RAII GetIteratorIRGenerator : public IRGenerator {
431   HandleValue val_;
432 
433   AttachDecision tryAttachNativeIterator(ValOperandId valId);
434   AttachDecision tryAttachNullOrUndefined(ValOperandId valId);
435   AttachDecision tryAttachMegamorphic(ValOperandId valId);
436 
437  public:
438   GetIteratorIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
439                          ICState state, HandleValue value);
440 
441   AttachDecision tryAttachStub();
442 
443   void trackAttached(const char* name);
444 };
445 
446 class MOZ_RAII OptimizeSpreadCallIRGenerator : public IRGenerator {
447   HandleValue val_;
448 
449   AttachDecision tryAttachArray();
450   AttachDecision tryAttachArguments();
451   AttachDecision tryAttachNotOptimizable();
452 
453  public:
454   OptimizeSpreadCallIRGenerator(JSContext* cx, HandleScript script,
455                                 jsbytecode* pc, ICState state,
456                                 HandleValue value);
457 
458   AttachDecision tryAttachStub();
459 
460   void trackAttached(const char* name);
461 };
462 
463 enum class StringChar { CodeAt, At };
464 enum class ScriptedThisResult { NoAction, UninitializedThis, PlainObjectShape };
465 
466 class MOZ_RAII CallIRGenerator : public IRGenerator {
467  private:
468   JSOp op_;
469   uint32_t argc_;
470   HandleValue callee_;
471   HandleValue thisval_;
472   HandleValue newTarget_;
473   HandleValueArray args_;
474 
475   ScriptedThisResult getThisShapeForScripted(HandleFunction calleeFunc,
476                                              MutableHandleShape result);
477 
478   void emitNativeCalleeGuard(JSFunction* callee);
479   void emitCalleeGuard(ObjOperandId calleeId, JSFunction* callee);
480 
481   bool canAttachAtomicsReadWriteModify();
482 
483   struct AtomicsReadWriteModifyOperands {
484     ObjOperandId objId;
485     IntPtrOperandId intPtrIndexId;
486     OperandId numericValueId;
487   };
488 
489   AtomicsReadWriteModifyOperands emitAtomicsReadWriteModifyOperands(
490       HandleFunction callee);
491 
492   AttachDecision tryAttachArrayPush(HandleFunction callee);
493   AttachDecision tryAttachArrayPopShift(HandleFunction callee,
494                                         InlinableNative native);
495   AttachDecision tryAttachArrayJoin(HandleFunction callee);
496   AttachDecision tryAttachArraySlice(HandleFunction callee);
497   AttachDecision tryAttachArrayIsArray(HandleFunction callee);
498   AttachDecision tryAttachDataViewGet(HandleFunction callee, Scalar::Type type);
499   AttachDecision tryAttachDataViewSet(HandleFunction callee, Scalar::Type type);
500   AttachDecision tryAttachUnsafeGetReservedSlot(HandleFunction callee,
501                                                 InlinableNative native);
502   AttachDecision tryAttachUnsafeSetReservedSlot(HandleFunction callee);
503   AttachDecision tryAttachIsSuspendedGenerator(HandleFunction callee);
504   AttachDecision tryAttachToObject(HandleFunction callee,
505                                    InlinableNative native);
506   AttachDecision tryAttachToInteger(HandleFunction callee);
507   AttachDecision tryAttachToLength(HandleFunction callee);
508   AttachDecision tryAttachIsObject(HandleFunction callee);
509   AttachDecision tryAttachIsPackedArray(HandleFunction callee);
510   AttachDecision tryAttachIsCallable(HandleFunction callee);
511   AttachDecision tryAttachIsConstructor(HandleFunction callee);
512   AttachDecision tryAttachIsCrossRealmArrayConstructor(HandleFunction callee);
513   AttachDecision tryAttachGuardToClass(HandleFunction callee,
514                                        InlinableNative native);
515   AttachDecision tryAttachHasClass(HandleFunction callee, const JSClass* clasp,
516                                    bool isPossiblyWrapped);
517   AttachDecision tryAttachRegExpMatcherSearcherTester(HandleFunction callee,
518                                                       InlinableNative native);
519   AttachDecision tryAttachRegExpPrototypeOptimizable(HandleFunction callee);
520   AttachDecision tryAttachRegExpInstanceOptimizable(HandleFunction callee);
521   AttachDecision tryAttachGetFirstDollarIndex(HandleFunction callee);
522   AttachDecision tryAttachSubstringKernel(HandleFunction callee);
523   AttachDecision tryAttachObjectHasPrototype(HandleFunction callee);
524   AttachDecision tryAttachString(HandleFunction callee);
525   AttachDecision tryAttachStringConstructor(HandleFunction callee);
526   AttachDecision tryAttachStringToStringValueOf(HandleFunction callee);
527   AttachDecision tryAttachStringChar(HandleFunction callee, StringChar kind);
528   AttachDecision tryAttachStringCharCodeAt(HandleFunction callee);
529   AttachDecision tryAttachStringCharAt(HandleFunction callee);
530   AttachDecision tryAttachStringFromCharCode(HandleFunction callee);
531   AttachDecision tryAttachStringFromCodePoint(HandleFunction callee);
532   AttachDecision tryAttachStringToLowerCase(HandleFunction callee);
533   AttachDecision tryAttachStringToUpperCase(HandleFunction callee);
534   AttachDecision tryAttachStringReplaceString(HandleFunction callee);
535   AttachDecision tryAttachStringSplitString(HandleFunction callee);
536   AttachDecision tryAttachMathRandom(HandleFunction callee);
537   AttachDecision tryAttachMathAbs(HandleFunction callee);
538   AttachDecision tryAttachMathClz32(HandleFunction callee);
539   AttachDecision tryAttachMathSign(HandleFunction callee);
540   AttachDecision tryAttachMathImul(HandleFunction callee);
541   AttachDecision tryAttachMathFloor(HandleFunction callee);
542   AttachDecision tryAttachMathCeil(HandleFunction callee);
543   AttachDecision tryAttachMathTrunc(HandleFunction callee);
544   AttachDecision tryAttachMathRound(HandleFunction callee);
545   AttachDecision tryAttachMathSqrt(HandleFunction callee);
546   AttachDecision tryAttachMathFRound(HandleFunction callee);
547   AttachDecision tryAttachMathHypot(HandleFunction callee);
548   AttachDecision tryAttachMathATan2(HandleFunction callee);
549   AttachDecision tryAttachMathFunction(HandleFunction callee,
550                                        UnaryMathFunction fun);
551   AttachDecision tryAttachMathPow(HandleFunction callee);
552   AttachDecision tryAttachMathMinMax(HandleFunction callee, bool isMax);
553   AttachDecision tryAttachSpreadMathMinMax(HandleFunction callee, bool isMax);
554   AttachDecision tryAttachIsTypedArray(HandleFunction callee,
555                                        bool isPossiblyWrapped);
556   AttachDecision tryAttachIsTypedArrayConstructor(HandleFunction callee);
557   AttachDecision tryAttachTypedArrayByteOffset(HandleFunction callee);
558   AttachDecision tryAttachTypedArrayElementSize(HandleFunction callee);
559   AttachDecision tryAttachTypedArrayLength(HandleFunction callee,
560                                            bool isPossiblyWrapped);
561   AttachDecision tryAttachArrayBufferByteLength(HandleFunction callee,
562                                                 bool isPossiblyWrapped);
563   AttachDecision tryAttachIsConstructing(HandleFunction callee);
564   AttachDecision tryAttachGetNextMapSetEntryForIterator(HandleFunction callee,
565                                                         bool isMap);
566   AttachDecision tryAttachFinishBoundFunctionInit(HandleFunction callee);
567   AttachDecision tryAttachNewArrayIterator(HandleFunction callee);
568   AttachDecision tryAttachNewStringIterator(HandleFunction callee);
569   AttachDecision tryAttachNewRegExpStringIterator(HandleFunction callee);
570   AttachDecision tryAttachArrayIteratorPrototypeOptimizable(
571       HandleFunction callee);
572   AttachDecision tryAttachObjectCreate(HandleFunction callee);
573   AttachDecision tryAttachArrayConstructor(HandleFunction callee);
574   AttachDecision tryAttachTypedArrayConstructor(HandleFunction callee);
575   AttachDecision tryAttachNumberToString(HandleFunction callee);
576   AttachDecision tryAttachReflectGetPrototypeOf(HandleFunction callee);
577   AttachDecision tryAttachAtomicsCompareExchange(HandleFunction callee);
578   AttachDecision tryAttachAtomicsExchange(HandleFunction callee);
579   AttachDecision tryAttachAtomicsAdd(HandleFunction callee);
580   AttachDecision tryAttachAtomicsSub(HandleFunction callee);
581   AttachDecision tryAttachAtomicsAnd(HandleFunction callee);
582   AttachDecision tryAttachAtomicsOr(HandleFunction callee);
583   AttachDecision tryAttachAtomicsXor(HandleFunction callee);
584   AttachDecision tryAttachAtomicsLoad(HandleFunction callee);
585   AttachDecision tryAttachAtomicsStore(HandleFunction callee);
586   AttachDecision tryAttachAtomicsIsLockFree(HandleFunction callee);
587   AttachDecision tryAttachBoolean(HandleFunction callee);
588   AttachDecision tryAttachBailout(HandleFunction callee);
589   AttachDecision tryAttachAssertFloat32(HandleFunction callee);
590   AttachDecision tryAttachAssertRecoveredOnBailout(HandleFunction callee);
591   AttachDecision tryAttachObjectIs(HandleFunction callee);
592   AttachDecision tryAttachObjectIsPrototypeOf(HandleFunction callee);
593   AttachDecision tryAttachObjectToString(HandleFunction callee);
594   AttachDecision tryAttachBigIntAsIntN(HandleFunction callee);
595   AttachDecision tryAttachBigIntAsUintN(HandleFunction callee);
596   AttachDecision tryAttachSetHas(HandleFunction callee);
597   AttachDecision tryAttachMapHas(HandleFunction callee);
598   AttachDecision tryAttachMapGet(HandleFunction callee);
599 
600   AttachDecision tryAttachFunCall(HandleFunction calleeFunc);
601   AttachDecision tryAttachFunApply(HandleFunction calleeFunc);
602   AttachDecision tryAttachCallScripted(HandleFunction calleeFunc);
603   AttachDecision tryAttachInlinableNative(HandleFunction calleeFunc);
604   AttachDecision tryAttachWasmCall(HandleFunction calleeFunc);
605   AttachDecision tryAttachCallNative(HandleFunction calleeFunc);
606   AttachDecision tryAttachCallHook(HandleObject calleeObj);
607 
608   void trackAttached(const char* name);
609 
610  public:
611   CallIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, JSOp op,
612                   ICState state, uint32_t argc, HandleValue callee,
613                   HandleValue thisval, HandleValue newTarget,
614                   HandleValueArray args);
615 
616   AttachDecision tryAttachStub();
617 };
618 
619 class MOZ_RAII CompareIRGenerator : public IRGenerator {
620   JSOp op_;
621   HandleValue lhsVal_;
622   HandleValue rhsVal_;
623 
624   AttachDecision tryAttachString(ValOperandId lhsId, ValOperandId rhsId);
625   AttachDecision tryAttachObject(ValOperandId lhsId, ValOperandId rhsId);
626   AttachDecision tryAttachSymbol(ValOperandId lhsId, ValOperandId rhsId);
627   AttachDecision tryAttachStrictDifferentTypes(ValOperandId lhsId,
628                                                ValOperandId rhsId);
629   AttachDecision tryAttachInt32(ValOperandId lhsId, ValOperandId rhsId);
630   AttachDecision tryAttachNumber(ValOperandId lhsId, ValOperandId rhsId);
631   AttachDecision tryAttachBigInt(ValOperandId lhsId, ValOperandId rhsId);
632   AttachDecision tryAttachNumberUndefined(ValOperandId lhsId,
633                                           ValOperandId rhsId);
634   AttachDecision tryAttachAnyNullUndefined(ValOperandId lhsId,
635                                            ValOperandId rhsId);
636   AttachDecision tryAttachNullUndefined(ValOperandId lhsId, ValOperandId rhsId);
637   AttachDecision tryAttachStringNumber(ValOperandId lhsId, ValOperandId rhsId);
638   AttachDecision tryAttachPrimitiveSymbol(ValOperandId lhsId,
639                                           ValOperandId rhsId);
640   AttachDecision tryAttachBoolStringOrNumber(ValOperandId lhsId,
641                                              ValOperandId rhsId);
642   AttachDecision tryAttachBigIntInt32(ValOperandId lhsId, ValOperandId rhsId);
643   AttachDecision tryAttachBigIntNumber(ValOperandId lhsId, ValOperandId rhsId);
644   AttachDecision tryAttachBigIntString(ValOperandId lhsId, ValOperandId rhsId);
645 
646   void trackAttached(const char* name);
647 
648  public:
649   CompareIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState state,
650                      JSOp op, HandleValue lhsVal, HandleValue rhsVal);
651 
652   AttachDecision tryAttachStub();
653 };
654 
655 class MOZ_RAII ToBoolIRGenerator : public IRGenerator {
656   HandleValue val_;
657 
658   AttachDecision tryAttachBool();
659   AttachDecision tryAttachInt32();
660   AttachDecision tryAttachNumber();
661   AttachDecision tryAttachString();
662   AttachDecision tryAttachSymbol();
663   AttachDecision tryAttachNullOrUndefined();
664   AttachDecision tryAttachObject();
665   AttachDecision tryAttachBigInt();
666 
667   void trackAttached(const char* name);
668 
669  public:
670   ToBoolIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState state,
671                     HandleValue val);
672 
673   AttachDecision tryAttachStub();
674 };
675 
676 class MOZ_RAII GetIntrinsicIRGenerator : public IRGenerator {
677   HandleValue val_;
678 
679   void trackAttached(const char* name);
680 
681  public:
682   GetIntrinsicIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
683                           ICState state, HandleValue val);
684 
685   AttachDecision tryAttachStub();
686 };
687 
688 class MOZ_RAII UnaryArithIRGenerator : public IRGenerator {
689   JSOp op_;
690   HandleValue val_;
691   HandleValue res_;
692 
693   AttachDecision tryAttachInt32();
694   AttachDecision tryAttachNumber();
695   AttachDecision tryAttachBitwise();
696   AttachDecision tryAttachBigInt();
697   AttachDecision tryAttachStringInt32();
698   AttachDecision tryAttachStringNumber();
699 
700   void trackAttached(const char* name);
701 
702  public:
703   UnaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
704                         ICState state, JSOp op, HandleValue val,
705                         HandleValue res);
706 
707   AttachDecision tryAttachStub();
708 };
709 
710 class MOZ_RAII ToPropertyKeyIRGenerator : public IRGenerator {
711   HandleValue val_;
712 
713   AttachDecision tryAttachInt32();
714   AttachDecision tryAttachNumber();
715   AttachDecision tryAttachString();
716   AttachDecision tryAttachSymbol();
717 
718   void trackAttached(const char* name);
719 
720  public:
721   ToPropertyKeyIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
722                            ICState state, HandleValue val);
723 
724   AttachDecision tryAttachStub();
725 };
726 
727 class MOZ_RAII BinaryArithIRGenerator : public IRGenerator {
728   JSOp op_;
729   HandleValue lhs_;
730   HandleValue rhs_;
731   HandleValue res_;
732 
733   void trackAttached(const char* name);
734 
735   AttachDecision tryAttachInt32();
736   AttachDecision tryAttachDouble();
737   AttachDecision tryAttachBitwise();
738   AttachDecision tryAttachStringConcat();
739   AttachDecision tryAttachStringObjectConcat();
740   AttachDecision tryAttachStringNumberConcat();
741   AttachDecision tryAttachStringBooleanConcat();
742   AttachDecision tryAttachBigInt();
743   AttachDecision tryAttachStringInt32Arith();
744 
745  public:
746   BinaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
747                          ICState state, JSOp op, HandleValue lhs,
748                          HandleValue rhs, HandleValue res);
749 
750   AttachDecision tryAttachStub();
751 };
752 
753 class MOZ_RAII NewArrayIRGenerator : public IRGenerator {
754 #ifdef JS_CACHEIR_SPEW
755   JSOp op_;
756 #endif
757   HandleObject templateObject_;
758   BaselineFrame* frame_;
759 
760   void trackAttached(const char* name);
761 
762  public:
763   NewArrayIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
764                       ICState state, JSOp op, HandleObject templateObj,
765                       BaselineFrame* frame);
766 
767   AttachDecision tryAttachStub();
768   AttachDecision tryAttachArrayObject();
769 };
770 
771 class MOZ_RAII NewObjectIRGenerator : public IRGenerator {
772 #ifdef JS_CACHEIR_SPEW
773   JSOp op_;
774 #endif
775   HandleObject templateObject_;
776   BaselineFrame* frame_;
777 
778   void trackAttached(const char* name);
779 
780  public:
781   NewObjectIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
782                        ICState state, JSOp op, HandleObject templateObj,
783                        BaselineFrame* frame);
784 
785   AttachDecision tryAttachStub();
786   AttachDecision tryAttachPlainObject();
787 };
788 
BytecodeOpCanHaveAllocSite(JSOp op)789 inline bool BytecodeOpCanHaveAllocSite(JSOp op) {
790   return op == JSOp::NewArray || op == JSOp::NewObject || op == JSOp::NewInit;
791 }
792 
793 // Retrieve Xray JIT info set by the embedder.
794 extern JS::XrayJitInfo* GetXrayJitInfo();
795 
796 }  // namespace jit
797 }  // namespace js
798 
799 #endif /* jit_CacheIRGenerator_h */
800