tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CacheIRGenerator.h (46682B)


      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 #include "mozilla/Maybe.h"
     13 
     14 #include <stdint.h>
     15 
     16 #include "jstypes.h"
     17 #include "NamespaceImports.h"
     18 
     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 class RegExpFlags;
     35 }  // namespace JS
     36 
     37 namespace js {
     38 
     39 class BoundFunctionObject;
     40 class NativeObject;
     41 class ObjectFuse;
     42 class PropertyResult;
     43 class ProxyObject;
     44 enum class UnaryMathFunction : uint8_t;
     45 enum class SetSlotOptimizable;
     46 
     47 namespace jit {
     48 
     49 class BaselineFrame;
     50 class Label;
     51 class MacroAssembler;
     52 struct Register;
     53 enum class InlinableNative : uint16_t;
     54 
     55 // Some ops refer to shapes that might be in other zones. Instead of putting
     56 // cross-zone pointers in the caches themselves (which would complicate tracing
     57 // enormously), these ops instead contain wrappers for objects in the target
     58 // zone, which refer to the actual shape via a reserved slot.
     59 void LoadShapeWrapperContents(MacroAssembler& masm, Register obj, Register dst,
     60                              Label* failure);
     61 
     62 enum class NativeGetPropKind {
     63  None,
     64  Missing,
     65  Slot,
     66  NativeGetter,
     67  ScriptedGetter,
     68 };
     69 
     70 class MOZ_RAII IRGenerator {
     71 protected:
     72  CacheIRWriter writer;
     73  JSContext* cx_;
     74  HandleScript script_;
     75  jsbytecode* pc_;
     76  BaselineFrame* maybeFrame_;
     77  CacheKind cacheKind_;
     78  ICState::Mode mode_;
     79  bool isFirstStub_;
     80  uint8_t numOptimizedStubs_;
     81 
     82  // Important: This pointer may be passed to the profiler. If this is non-null,
     83  // it must point to a C string literal with static lifetime, not a heap- or
     84  // stack- allocated string.
     85  const char* stubName_ = nullptr;
     86 
     87  IRGenerator(const IRGenerator&) = delete;
     88  IRGenerator& operator=(const IRGenerator&) = delete;
     89 
     90  JSOp jsop() const { return JSOp(*pc_); }
     91 
     92  bool maybeGuardInt32Index(const Value& index, ValOperandId indexId,
     93                            uint32_t* int32Index, Int32OperandId* int32IndexId);
     94 
     95  IntPtrOperandId guardToIntPtrIndex(const Value& index, ValOperandId indexId,
     96                                     bool supportOOB);
     97 
     98  ObjOperandId guardDOMProxyExpandoObjectAndShape(ProxyObject* obj,
     99                                                  ObjOperandId objId,
    100                                                  const Value& expandoVal,
    101                                                  NativeObject* expandoObj);
    102 
    103  void emitIdGuard(ValOperandId valId, const Value& idVal, jsid id);
    104 
    105  OperandId emitNumericGuard(ValOperandId valId, const Value& v,
    106                             Scalar::Type type);
    107 
    108  StringOperandId emitToStringGuard(ValOperandId id, const Value& v);
    109 
    110  void emitCalleeGuard(ObjOperandId calleeId, JSFunction* callee);
    111 
    112  void emitOptimisticClassGuard(ObjOperandId objId, JSObject* obj,
    113                                GuardClassKind kind);
    114 
    115  enum class AccessorKind { Getter, Setter };
    116  void emitGuardGetterSetterSlot(NativeObject* holder, PropertyInfo prop,
    117                                 ObjOperandId holderId, AccessorKind kind,
    118                                 bool holderIsConstant = false);
    119  void emitCallGetterResultNoGuards(NativeGetPropKind kind, NativeObject* obj,
    120                                    NativeObject* holder, PropertyInfo prop,
    121                                    ValOperandId receiverId);
    122  void emitCallDOMGetterResultNoGuards(NativeObject* holder, PropertyInfo prop,
    123                                       ObjOperandId objId);
    124 
    125  void emitCallAccessorGuards(NativeObject* obj, NativeObject* holder,
    126                              HandleId id, PropertyInfo prop,
    127                              ObjOperandId objId, AccessorKind accessorKind);
    128 
    129  bool canOptimizeConstantDataProperty(NativeObject* holder, PropertyInfo prop,
    130                                       ObjectFuse** objFuse);
    131  void emitConstantDataPropertyResult(NativeObject* holder,
    132                                      ObjOperandId holderId, PropertyKey key,
    133                                      PropertyInfo prop, ObjectFuse* objFuse);
    134  void emitLoadDataPropertyResult(NativeObject* obj, NativeObject* holder,
    135                                  PropertyKey key, PropertyInfo prop,
    136                                  ObjOperandId objId);
    137 
    138  bool canOptimizeConstantAccessorProperty(NativeObject* holder,
    139                                           PropertyInfo prop,
    140                                           ObjectFuse** objFuse);
    141  void emitGuardConstantAccessorProperty(NativeObject* holder,
    142                                         ObjOperandId holderId, PropertyKey key,
    143                                         PropertyInfo prop,
    144                                         ObjectFuse* objFuse);
    145 
    146  gc::AllocSite* maybeCreateAllocSite();
    147 
    148  friend class CacheIRSpewer;
    149  friend class InlinableNativeIRGenerator;
    150 
    151 public:
    152  explicit IRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
    153                       CacheKind cacheKind, ICState state,
    154                       BaselineFrame* maybeFrame = nullptr);
    155 
    156  const CacheIRWriter& writerRef() const { return writer; }
    157  CacheKind cacheKind() const { return cacheKind_; }
    158 
    159  // See comment on `stubName_` above.
    160  const char* stubName() const { return stubName_; }
    161 
    162  static constexpr char* NotAttached = nullptr;
    163 };
    164 
    165 // GetPropIRGenerator generates CacheIR for a GetProp IC.
    166 class MOZ_RAII GetPropIRGenerator : public IRGenerator {
    167  HandleValue val_;
    168  HandleValue idVal_;
    169  HandleValue receiverVal_;
    170 
    171  friend class InlinableNativeIRGenerator;
    172 
    173  AttachDecision tryAttachNative(HandleObject obj, ObjOperandId objId,
    174                                 HandleId id, ValOperandId receiverId);
    175  AttachDecision tryAttachInlinableNativeGetter(Handle<NativeObject*> holder,
    176                                                PropertyInfo prop,
    177                                                ValOperandId receiverId);
    178  AttachDecision tryAttachObjectLength(HandleObject obj, ObjOperandId objId,
    179                                       HandleId id);
    180  AttachDecision tryAttachModuleNamespace(HandleObject obj, ObjOperandId objId,
    181                                          HandleId id);
    182  AttachDecision tryAttachWindowProxy(HandleObject obj, ObjOperandId objId,
    183                                      HandleId id);
    184  AttachDecision tryAttachCrossCompartmentWrapper(HandleObject obj,
    185                                                  ObjOperandId objId,
    186                                                  HandleId id);
    187  AttachDecision tryAttachXrayCrossCompartmentWrapper(HandleObject obj,
    188                                                      ObjOperandId objId,
    189                                                      HandleId id,
    190                                                      ValOperandId receiverId);
    191  AttachDecision tryAttachFunction(HandleObject obj, ObjOperandId objId,
    192                                   HandleId id);
    193  AttachDecision tryAttachArgumentsObjectIterator(HandleObject obj,
    194                                                  ObjOperandId objId,
    195                                                  HandleId id);
    196 
    197  AttachDecision tryAttachGenericProxy(Handle<ProxyObject*> obj,
    198                                       ObjOperandId objId, HandleId id,
    199                                       bool handleDOMProxies);
    200 #ifdef JS_PUNBOX64
    201  AttachDecision tryAttachScriptedProxy(Handle<ProxyObject*> obj,
    202                                        ObjOperandId objId, HandleId id);
    203 #endif
    204  AttachDecision tryAttachDOMProxyExpando(Handle<ProxyObject*> obj,
    205                                          ObjOperandId objId, HandleId id,
    206                                          ValOperandId receiverId);
    207  AttachDecision tryAttachDOMProxyShadowed(Handle<ProxyObject*> obj,
    208                                           ObjOperandId objId, HandleId id);
    209  AttachDecision tryAttachDOMProxyUnshadowed(Handle<ProxyObject*> obj,
    210                                             ObjOperandId objId, HandleId id,
    211                                             ValOperandId receiverId);
    212  AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId,
    213                                HandleId id, ValOperandId receiverId);
    214 
    215  AttachDecision tryAttachPrimitive(ValOperandId valId, HandleId id);
    216  AttachDecision tryAttachStringChar(ValOperandId valId, ValOperandId indexId);
    217  AttachDecision tryAttachStringLength(ValOperandId valId, HandleId id);
    218 
    219  AttachDecision tryAttachArgumentsObjectArg(HandleObject obj,
    220                                             ObjOperandId objId, uint32_t index,
    221                                             Int32OperandId indexId);
    222  AttachDecision tryAttachArgumentsObjectArgHole(HandleObject obj,
    223                                                 ObjOperandId objId,
    224                                                 uint32_t index,
    225                                                 Int32OperandId indexId);
    226  AttachDecision tryAttachArgumentsObjectCallee(HandleObject obj,
    227                                                ObjOperandId objId,
    228                                                HandleId id);
    229 
    230  AttachDecision tryAttachDenseElement(HandleObject obj, ObjOperandId objId,
    231                                       uint32_t index, Int32OperandId indexId);
    232  AttachDecision tryAttachDenseElementHole(HandleObject obj, ObjOperandId objId,
    233                                           uint32_t index,
    234                                           Int32OperandId indexId);
    235  AttachDecision tryAttachSparseElement(HandleObject obj, ObjOperandId objId,
    236                                        uint32_t index, Int32OperandId indexId);
    237  AttachDecision tryAttachTypedArrayElement(HandleObject obj,
    238                                            ObjOperandId objId);
    239 
    240  AttachDecision tryAttachGenericElement(HandleObject obj, ObjOperandId objId,
    241                                         uint32_t index, Int32OperandId indexId,
    242                                         ValOperandId receiverId);
    243 
    244  AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId);
    245 
    246  void attachMegamorphicNativeSlot(ObjOperandId objId, jsid id);
    247 
    248  void attachMegamorphicNativeSlotPermissive(ObjOperandId objId, jsid id);
    249 
    250  ValOperandId getElemKeyValueId() const {
    251    MOZ_ASSERT(cacheKind_ == CacheKind::GetElem ||
    252               cacheKind_ == CacheKind::GetElemSuper);
    253    return ValOperandId(1);
    254  }
    255 
    256  ValOperandId getSuperReceiverValueId() const {
    257    if (cacheKind_ == CacheKind::GetPropSuper) {
    258      return ValOperandId(1);
    259    }
    260 
    261    MOZ_ASSERT(cacheKind_ == CacheKind::GetElemSuper);
    262    return ValOperandId(2);
    263  }
    264 
    265  bool isSuper() const {
    266    return (cacheKind_ == CacheKind::GetPropSuper ||
    267            cacheKind_ == CacheKind::GetElemSuper);
    268  }
    269 
    270  // If this is a GetElem cache, emit instructions to guard the incoming Value
    271  // matches |id|.
    272  void maybeEmitIdGuard(jsid id);
    273 
    274  void emitCallGetterResultGuards(NativeObject* obj, NativeObject* holder,
    275                                  HandleId id, PropertyInfo prop,
    276                                  ObjOperandId objId);
    277  void emitCallGetterResult(NativeGetPropKind kind, Handle<NativeObject*> obj,
    278                            Handle<NativeObject*> holder, HandleId id,
    279                            PropertyInfo prop, ObjOperandId objId,
    280                            ValOperandId receiverId);
    281  void emitCallDOMGetterResult(NativeObject* obj, NativeObject* holder,
    282                               HandleId id, PropertyInfo prop,
    283                               ObjOperandId objId);
    284 
    285  void trackAttached(const char* name /* must be a C string literal */);
    286 
    287 public:
    288  GetPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
    289                     ICState state, CacheKind cacheKind, HandleValue val,
    290                     HandleValue idVal, HandleValue receiverVal);
    291 
    292  AttachDecision tryAttachStub();
    293 };
    294 
    295 // GetNameIRGenerator generates CacheIR for a GetName IC.
    296 class MOZ_RAII GetNameIRGenerator : public IRGenerator {
    297  HandleObject env_;
    298  Handle<PropertyName*> name_;
    299 
    300  AttachDecision tryAttachGlobalNameValue(ObjOperandId objId, HandleId id);
    301  AttachDecision tryAttachGlobalNameGetter(ObjOperandId objId, HandleId id);
    302  AttachDecision tryAttachEnvironmentName(ObjOperandId objId, HandleId id);
    303 
    304  void trackAttached(const char* name /* must be a C string literal */);
    305 
    306 public:
    307  GetNameIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
    308                     ICState state, HandleObject env,
    309                     Handle<PropertyName*> name);
    310 
    311  AttachDecision tryAttachStub();
    312 };
    313 
    314 // BindNameIRGenerator generates CacheIR for a BindName IC.
    315 class MOZ_RAII BindNameIRGenerator : public IRGenerator {
    316  HandleObject env_;
    317  Handle<PropertyName*> name_;
    318 
    319  AttachDecision tryAttachGlobalName(ObjOperandId objId, HandleId id);
    320  AttachDecision tryAttachEnvironmentName(ObjOperandId objId, HandleId id);
    321 
    322  void trackAttached(const char* name /* must be a C string literal */);
    323 
    324 public:
    325  BindNameIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
    326                      ICState state, HandleObject env,
    327                      Handle<PropertyName*> name);
    328 
    329  AttachDecision tryAttachStub();
    330 };
    331 
    332 // SetPropIRGenerator generates CacheIR for a SetProp IC.
    333 class MOZ_RAII SetPropIRGenerator : public IRGenerator {
    334  HandleValue lhsVal_;
    335  HandleValue idVal_;
    336  HandleValue rhsVal_;
    337 
    338 public:
    339  enum class DeferType { None, AddSlot };
    340 
    341 private:
    342  DeferType deferType_ = DeferType::None;
    343 
    344  ValOperandId setElemKeyValueId() const {
    345    MOZ_ASSERT(cacheKind_ == CacheKind::SetElem);
    346    return ValOperandId(1);
    347  }
    348 
    349  ValOperandId rhsValueId() const {
    350    if (cacheKind_ == CacheKind::SetProp) {
    351      return ValOperandId(1);
    352    }
    353    MOZ_ASSERT(cacheKind_ == CacheKind::SetElem);
    354    return ValOperandId(2);
    355  }
    356 
    357  // If this is a SetElem cache, emit instructions to guard the incoming Value
    358  // matches |id|.
    359  void maybeEmitIdGuard(jsid id);
    360 
    361  SetSlotOptimizable canAttachNativeSetSlot(JSObject* obj, PropertyKey id,
    362                                            mozilla::Maybe<PropertyInfo>* prop);
    363 
    364  AttachDecision tryAttachNativeSetSlot(HandleObject obj, ObjOperandId objId,
    365                                        HandleId id, ValOperandId rhsId);
    366  AttachDecision tryAttachMegamorphicSetSlot(HandleObject obj,
    367                                             ObjOperandId objId, HandleId id,
    368                                             ValOperandId rhsId);
    369  AttachDecision tryAttachSetter(HandleObject obj, ObjOperandId objId,
    370                                 HandleId id, ValOperandId rhsId);
    371  AttachDecision tryAttachSetArrayLength(HandleObject obj, ObjOperandId objId,
    372                                         HandleId id, ValOperandId rhsId);
    373  AttachDecision tryAttachWindowProxy(HandleObject obj, ObjOperandId objId,
    374                                      HandleId id, ValOperandId rhsId);
    375 
    376  AttachDecision tryAttachSetDenseElement(HandleObject obj, ObjOperandId objId,
    377                                          uint32_t index,
    378                                          Int32OperandId indexId,
    379                                          ValOperandId rhsId);
    380  AttachDecision tryAttachSetTypedArrayElement(HandleObject obj,
    381                                               ObjOperandId objId,
    382                                               ValOperandId rhsId);
    383 
    384  AttachDecision tryAttachSetDenseElementHole(HandleObject obj,
    385                                              ObjOperandId objId,
    386                                              uint32_t index,
    387                                              Int32OperandId indexId,
    388                                              ValOperandId rhsId);
    389 
    390  AttachDecision tryAttachAddOrUpdateSparseElement(HandleObject obj,
    391                                                   ObjOperandId objId,
    392                                                   uint32_t index,
    393                                                   Int32OperandId indexId,
    394                                                   ValOperandId rhsId);
    395 
    396  AttachDecision tryAttachGenericProxy(Handle<ProxyObject*> obj,
    397                                       ObjOperandId objId, HandleId id,
    398                                       ValOperandId rhsId,
    399                                       bool handleDOMProxies);
    400  AttachDecision tryAttachDOMProxyShadowed(Handle<ProxyObject*> obj,
    401                                           ObjOperandId objId, HandleId id,
    402                                           ValOperandId rhsId);
    403  AttachDecision tryAttachDOMProxyUnshadowed(Handle<ProxyObject*> obj,
    404                                             ObjOperandId objId, HandleId id,
    405                                             ValOperandId rhsId);
    406  AttachDecision tryAttachDOMProxyExpando(Handle<ProxyObject*> obj,
    407                                          ObjOperandId objId, HandleId id,
    408                                          ValOperandId rhsId);
    409  AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId,
    410                                HandleId id, ValOperandId rhsId);
    411  AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
    412                                       ValOperandId rhsId);
    413  AttachDecision tryAttachMegamorphicSetElement(HandleObject obj,
    414                                                ObjOperandId objId,
    415                                                ValOperandId rhsId);
    416 
    417  bool canAttachAddSlotStub(HandleObject obj, HandleId id);
    418 
    419  void emitCallSetterNoGuards(NativeObject* obj, NativeObject* holder,
    420                              PropertyInfo prop, ObjOperandId receiverId,
    421                              ValOperandId rhsId);
    422  void emitCallDOMSetterNoGuards(NativeObject* holder, PropertyInfo prop,
    423                                 ObjOperandId objId, ValOperandId rhsId);
    424 
    425 public:
    426  SetPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
    427                     CacheKind cacheKind, ICState state, HandleValue lhsVal,
    428                     HandleValue idVal, HandleValue rhsVal);
    429 
    430  AttachDecision tryAttachStub();
    431  AttachDecision tryAttachAddSlotStub(Handle<Shape*> oldShape);
    432  void trackAttached(const char* name /* must be a C string literal */);
    433 
    434  DeferType deferType() const { return deferType_; }
    435 };
    436 
    437 // HasPropIRGenerator generates CacheIR for a HasProp IC. Used for
    438 // CacheKind::In / CacheKind::HasOwn.
    439 class MOZ_RAII HasPropIRGenerator : public IRGenerator {
    440  HandleValue val_;
    441  HandleValue idVal_;
    442 
    443  AttachDecision tryAttachDense(HandleObject obj, ObjOperandId objId,
    444                                uint32_t index, Int32OperandId indexId);
    445  AttachDecision tryAttachDenseHole(HandleObject obj, ObjOperandId objId,
    446                                    uint32_t index, Int32OperandId indexId);
    447  AttachDecision tryAttachTypedArray(HandleObject obj, ObjOperandId objId,
    448                                     ValOperandId keyId);
    449  AttachDecision tryAttachSparse(HandleObject obj, ObjOperandId objId,
    450                                 Int32OperandId indexId);
    451  AttachDecision tryAttachArgumentsObjectArg(HandleObject obj,
    452                                             ObjOperandId objId,
    453                                             Int32OperandId indexId);
    454  AttachDecision tryAttachNamedProp(HandleObject obj, ObjOperandId objId,
    455                                    HandleId key, ValOperandId keyId);
    456  AttachDecision tryAttachMegamorphic(ObjOperandId objId, ValOperandId keyId);
    457  AttachDecision tryAttachSmallObjectVariableKey(HandleObject obj,
    458                                                 ObjOperandId objId, jsid key,
    459                                                 ValOperandId keyId);
    460  AttachDecision tryAttachNative(NativeObject* obj, ObjOperandId objId,
    461                                 jsid key, ValOperandId keyId,
    462                                 PropertyResult prop, NativeObject* holder);
    463  AttachDecision tryAttachSlotDoesNotExist(NativeObject* obj,
    464                                           ObjOperandId objId, jsid key,
    465                                           ValOperandId keyId);
    466  AttachDecision tryAttachDoesNotExist(HandleObject obj, ObjOperandId objId,
    467                                       HandleId key, ValOperandId keyId);
    468  AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
    469                                       ValOperandId keyId);
    470 
    471  void trackAttached(const char* name /* must be a C string literal */);
    472 
    473 public:
    474  // NOTE: Argument order is PROPERTY, OBJECT
    475  HasPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
    476                     ICState state, CacheKind cacheKind, HandleValue idVal,
    477                     HandleValue val);
    478 
    479  AttachDecision tryAttachStub();
    480 };
    481 
    482 class MOZ_RAII CheckPrivateFieldIRGenerator : public IRGenerator {
    483  HandleValue val_;
    484  HandleValue idVal_;
    485 
    486  AttachDecision tryAttachNative(NativeObject* obj, ObjOperandId objId,
    487                                 jsid key, ValOperandId keyId,
    488                                 PropertyResult prop);
    489 
    490  void trackAttached(const char* name /* must be a C string literal */);
    491 
    492 public:
    493  CheckPrivateFieldIRGenerator(JSContext* cx, HandleScript script,
    494                               jsbytecode* pc, ICState state,
    495                               CacheKind cacheKind, HandleValue idVal,
    496                               HandleValue val);
    497  AttachDecision tryAttachStub();
    498 };
    499 
    500 class MOZ_RAII InstanceOfIRGenerator : public IRGenerator {
    501  HandleValue lhsVal_;
    502  HandleObject rhsObj_;
    503 
    504  AttachDecision tryAttachFunction();
    505  void trackAttached(const char* name /* must be a C string literal */);
    506 
    507 public:
    508  InstanceOfIRGenerator(JSContext*, HandleScript, jsbytecode*, ICState,
    509                        HandleValue, HandleObject);
    510 
    511  AttachDecision tryAttachStub();
    512 };
    513 
    514 class MOZ_RAII TypeOfIRGenerator : public IRGenerator {
    515  HandleValue val_;
    516 
    517  AttachDecision tryAttachPrimitive(ValOperandId valId);
    518  AttachDecision tryAttachObject(ValOperandId valId);
    519  void trackAttached(const char* name /* must be a C string literal */);
    520 
    521 public:
    522  TypeOfIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState state,
    523                    HandleValue value);
    524 
    525  AttachDecision tryAttachStub();
    526 };
    527 
    528 class MOZ_RAII TypeOfEqIRGenerator : public IRGenerator {
    529  HandleValue val_;
    530  JSType type_;
    531  JSOp compareOp_;
    532 
    533  AttachDecision tryAttachPrimitive(ValOperandId valId);
    534  AttachDecision tryAttachObject(ValOperandId valId);
    535  void trackAttached(const char* name /* must be a C string literal */);
    536 
    537 public:
    538  TypeOfEqIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
    539                      ICState state, HandleValue value, JSType type,
    540                      JSOp compareOp);
    541 
    542  AttachDecision tryAttachStub();
    543 };
    544 
    545 class MOZ_RAII GetIteratorIRGenerator : public IRGenerator {
    546  HandleValue val_;
    547 
    548  AttachDecision tryAttachObject(ValOperandId valId);
    549  AttachDecision tryAttachNullOrUndefined(ValOperandId valId);
    550  AttachDecision tryAttachGeneric(ValOperandId valId);
    551 
    552 public:
    553  GetIteratorIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
    554                         ICState state, HandleValue value);
    555 
    556  AttachDecision tryAttachStub();
    557 
    558  void trackAttached(const char* name /* must be a C string literal */);
    559 };
    560 
    561 class MOZ_RAII OptimizeSpreadCallIRGenerator : public IRGenerator {
    562  HandleValue val_;
    563 
    564  AttachDecision tryAttachArray();
    565  AttachDecision tryAttachArguments();
    566  AttachDecision tryAttachNotOptimizable();
    567 
    568 public:
    569  OptimizeSpreadCallIRGenerator(JSContext* cx, HandleScript script,
    570                                jsbytecode* pc, ICState state,
    571                                HandleValue value);
    572 
    573  AttachDecision tryAttachStub();
    574 
    575  void trackAttached(const char* name /* must be a C string literal */);
    576 };
    577 
    578 class MOZ_RAII OptimizeGetIteratorIRGenerator : public IRGenerator {
    579  HandleValue val_;
    580 
    581  AttachDecision tryAttachArray();
    582  AttachDecision tryAttachNotOptimizable();
    583 
    584 public:
    585  OptimizeGetIteratorIRGenerator(JSContext* cx, HandleScript script,
    586                                 jsbytecode* pc, ICState state,
    587                                 HandleValue value);
    588 
    589  AttachDecision tryAttachStub();
    590 
    591  void trackAttached(const char* name /* must be a C string literal */);
    592 };
    593 
    594 enum class StringChar { CharCodeAt, CodePointAt, CharAt, At };
    595 enum class ScriptedThisResult { NoAction, UninitializedThis, PlainObjectShape };
    596 
    597 class MOZ_RAII CallIRGenerator : public IRGenerator {
    598 private:
    599  uint32_t argc_;
    600  HandleValue callee_;
    601  HandleValue thisval_;
    602  HandleValue newTarget_;
    603  HandleValueArray args_;
    604 
    605  friend class InlinableNativeIRGenerator;
    606 
    607  ScriptedThisResult getThisShapeForScripted(HandleFunction calleeFunc,
    608                                             Handle<JSObject*> newTarget,
    609                                             MutableHandle<Shape*> result);
    610 
    611  ObjOperandId emitFunCallOrApplyGuard(Int32OperandId argcId);
    612  ObjOperandId emitFunCallGuard(Int32OperandId argcId);
    613  ObjOperandId emitFunApplyGuard(Int32OperandId argcId);
    614  mozilla::Maybe<ObjOperandId> emitFunApplyArgsGuard(
    615      CallFlags::ArgFormat format);
    616 
    617  void emitCallScriptedGuards(ObjOperandId calleeObjId, JSFunction* calleeFunc,
    618                              Int32OperandId argcId, CallFlags flags,
    619                              Shape* thisShape, bool isBoundFunction);
    620 
    621  AttachDecision tryAttachFunCall(HandleFunction calleeFunc);
    622  AttachDecision tryAttachFunApply(HandleFunction calleeFunc);
    623  AttachDecision tryAttachCallScripted(HandleFunction calleeFunc);
    624  AttachDecision tryAttachInlinableNative(HandleFunction calleeFunc,
    625                                          CallFlags flags);
    626  AttachDecision tryAttachWasmCall(HandleFunction calleeFunc);
    627  AttachDecision tryAttachCallNative(HandleFunction calleeFunc);
    628  AttachDecision tryAttachCallHook(HandleObject calleeObj);
    629  AttachDecision tryAttachBoundFunction(Handle<BoundFunctionObject*> calleeObj);
    630  AttachDecision tryAttachBoundNative(Handle<BoundFunctionObject*> calleeObj);
    631  AttachDecision tryAttachBoundFunCall(Handle<BoundFunctionObject*> calleeObj);
    632  AttachDecision tryAttachBoundFunApply(Handle<BoundFunctionObject*> calleeObj);
    633  AttachDecision tryAttachFunCallBound(Handle<JSFunction*> callee);
    634  AttachDecision tryAttachFunApplyBound(Handle<JSFunction*> callee);
    635 
    636  void trackAttached(const char* name /* must be a C string literal */);
    637 
    638 public:
    639  CallIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
    640                  ICState state, BaselineFrame* frame, uint32_t argc,
    641                  HandleValue callee, HandleValue thisval,
    642                  HandleValue newTarget, HandleValueArray args);
    643 
    644  AttachDecision tryAttachStub();
    645 };
    646 
    647 class MOZ_RAII InlinableNativeIRGenerator {
    648  mozilla::Variant<CallIRGenerator*, GetPropIRGenerator*> gen_;
    649  IRGenerator& generator_;
    650  CacheIRWriter& writer;
    651  JSContext* cx_;
    652 
    653  HandleObject callee_;
    654  HandleFunction target_;
    655  HandleValue newTarget_;
    656  HandleValue thisval_;
    657  HandleValueArray args_;
    658  Handle<BoundFunctionObject*> boundTarget_;
    659  CallFlags flags_;
    660  uint32_t stackArgc_;
    661 
    662  // |this| for inlined accesor operations.
    663  ValOperandId receiverId_;
    664 
    665  HandleScript script() const { return generator_.script_; }
    666  JSObject* callee() const { return callee_; }
    667  bool isFirstStub() const { return generator_.isFirstStub_; }
    668  bool ignoresResult() const { return op() == JSOp::CallIgnoresRv; }
    669  JSOp op() const { return generator_.jsop(); }
    670  uint32_t stackArgc() const { return stackArgc_; }
    671 
    672  // Inlined native accessor for GetProp(Super) or GetElem(Super) operations.
    673  bool isAccessorOp() const { return !IsInvokeOp(op()); }
    674 
    675  bool isCalleeBoundFunction() const;
    676  BoundFunctionObject* boundCallee() const;
    677 
    678  bool isTargetBoundFunction() const { return boundTarget_ != nullptr; }
    679  BoundFunctionObject* boundTarget() const { return boundTarget_; }
    680 
    681  ObjOperandId emitNativeCalleeGuard(Int32OperandId argcId);
    682  void emitOptimisticClassGuard(ObjOperandId objId, JSObject* obj,
    683                                GuardClassKind kind) {
    684    generator_.emitOptimisticClassGuard(objId, obj, kind);
    685  }
    686 
    687  ObjOperandId emitLoadArgsArray();
    688 
    689  ValOperandId loadBoundArgument(ObjOperandId calleeId, size_t argIndex);
    690 
    691  ValOperandId loadThis(ObjOperandId calleeId);
    692 
    693  ValOperandId loadArgument(ObjOperandId calleeId, ArgumentKind kind);
    694 
    695  ValOperandId loadArgumentIntrinsic(ArgumentKind kind) {
    696    // Intrinsics can't be called through bound functions
    697    MOZ_ASSERT(target_->isIntrinsic());
    698    MOZ_ASSERT(flags_.getArgFormat() == CallFlags::Standard);
    699    return writer.loadArgumentFixedSlot(kind, stackArgc(), flags_);
    700  }
    701 
    702  bool hasBoundArguments() const;
    703 
    704  Int32OperandId initializeInputOperand() {
    705    // Input operands are already initialized for inlined accessors.
    706    if (isAccessorOp()) {
    707      return Int32OperandId();
    708    }
    709    return Int32OperandId(writer.setInputOperandId(0));
    710  }
    711 
    712  auto emitToStringGuard(ValOperandId id, const Value& v) {
    713    return generator_.emitToStringGuard(id, v);
    714  }
    715 
    716  auto emitNumericGuard(ValOperandId valId, const Value& v, Scalar::Type type) {
    717    return generator_.emitNumericGuard(valId, v, type);
    718  }
    719 
    720  auto guardToIntPtrIndex(const Value& index, ValOperandId indexId,
    721                          bool supportOOB) {
    722    return generator_.guardToIntPtrIndex(index, indexId, supportOOB);
    723  }
    724 
    725  bool canAttachAtomicsReadWriteModify();
    726 
    727  struct AtomicsReadWriteModifyOperands {
    728    ObjOperandId objId;
    729    IntPtrOperandId intPtrIndexId;
    730    OperandId numericValueId;
    731  };
    732 
    733  AtomicsReadWriteModifyOperands emitAtomicsReadWriteModifyOperands();
    734 
    735  enum class DateComponent {
    736    FullYear,
    737    Month,
    738    Date,
    739    Day,
    740    Hours,
    741    Minutes,
    742    Seconds,
    743  };
    744 
    745  AttachDecision tryAttachArrayPush();
    746  AttachDecision tryAttachArrayPopShift(InlinableNative native);
    747  AttachDecision tryAttachArrayJoin();
    748  AttachDecision tryAttachArraySlice();
    749  AttachDecision tryAttachArrayIsArray();
    750  AttachDecision tryAttachDataViewGet(Scalar::Type type);
    751  AttachDecision tryAttachDataViewSet(Scalar::Type type);
    752  AttachDecision tryAttachDataViewByteLength();
    753  AttachDecision tryAttachDataViewByteOffset();
    754  AttachDecision tryAttachFunctionBind();
    755  AttachDecision tryAttachSpecializedFunctionBind(
    756      Handle<JSObject*> target, Handle<BoundFunctionObject*> templateObj);
    757  AttachDecision tryAttachUnsafeGetReservedSlot(InlinableNative native);
    758  AttachDecision tryAttachUnsafeSetReservedSlot();
    759  AttachDecision tryAttachIsSuspendedGenerator();
    760  AttachDecision tryAttachToObject();
    761  AttachDecision tryAttachToInteger();
    762  AttachDecision tryAttachToLength();
    763  AttachDecision tryAttachIsObject();
    764  AttachDecision tryAttachIsPackedArray();
    765  AttachDecision tryAttachIsCallable();
    766  AttachDecision tryAttachIsConstructor();
    767  AttachDecision tryAttachIsCrossRealmArrayConstructor();
    768  AttachDecision tryAttachCanOptimizeArraySpecies();
    769  AttachDecision tryAttachGuardToClass(InlinableNative native);
    770  AttachDecision tryAttachGuardToClass(GuardClassKind kind);
    771  AttachDecision tryAttachGuardToArrayBuffer();
    772  AttachDecision tryAttachGuardToSharedArrayBuffer();
    773  AttachDecision tryAttachHasClass(const JSClass* clasp,
    774                                   bool isPossiblyWrapped);
    775  AttachDecision tryAttachRegExpFlag(JS::RegExpFlags flags);
    776  AttachDecision tryAttachRegExpMatcherSearcher(InlinableNative native);
    777  AttachDecision tryAttachRegExpSearcherLastLimit();
    778  AttachDecision tryAttachRegExpHasCaptureGroups();
    779  AttachDecision tryAttachIsRegExpPrototypeOptimizable();
    780  AttachDecision tryAttachIsOptimizableRegExpObject();
    781  AttachDecision tryAttachIntrinsicRegExpBuiltinExec(InlinableNative native);
    782  AttachDecision tryAttachIntrinsicRegExpExec(InlinableNative native);
    783  AttachDecision tryAttachGetFirstDollarIndex();
    784  AttachDecision tryAttachSubstringKernel();
    785  AttachDecision tryAttachString();
    786  AttachDecision tryAttachStringConstructor();
    787  AttachDecision tryAttachStringToStringValueOf();
    788  AttachDecision tryAttachStringChar(StringChar kind);
    789  AttachDecision tryAttachStringCharCodeAt();
    790  AttachDecision tryAttachStringCodePointAt();
    791  AttachDecision tryAttachStringCharAt();
    792  AttachDecision tryAttachStringAt();
    793  AttachDecision tryAttachStringFromCharCode();
    794  AttachDecision tryAttachStringFromCodePoint();
    795  AttachDecision tryAttachStringIncludes();
    796  AttachDecision tryAttachStringIndexOf();
    797  AttachDecision tryAttachStringLastIndexOf();
    798  AttachDecision tryAttachStringStartsWith();
    799  AttachDecision tryAttachStringEndsWith();
    800  AttachDecision tryAttachStringToLowerCase();
    801  AttachDecision tryAttachStringToUpperCase();
    802  AttachDecision tryAttachStringToLocaleLowerCase();
    803  AttachDecision tryAttachStringToLocaleUpperCase();
    804  AttachDecision tryAttachStringTrim();
    805  AttachDecision tryAttachStringTrimStart();
    806  AttachDecision tryAttachStringTrimEnd();
    807  AttachDecision tryAttachStringReplaceString();
    808  AttachDecision tryAttachStringSplitString();
    809  AttachDecision tryAttachMathRandom();
    810  AttachDecision tryAttachMathAbs();
    811  AttachDecision tryAttachMathClz32();
    812  AttachDecision tryAttachMathSign();
    813  AttachDecision tryAttachMathImul();
    814  AttachDecision tryAttachMathFloor();
    815  AttachDecision tryAttachMathCeil();
    816  AttachDecision tryAttachMathTrunc();
    817  AttachDecision tryAttachMathRound();
    818  AttachDecision tryAttachMathSqrt();
    819  AttachDecision tryAttachMathFRound();
    820  AttachDecision tryAttachMathF16Round();
    821  AttachDecision tryAttachMathHypot();
    822  AttachDecision tryAttachMathATan2();
    823  AttachDecision tryAttachMathFunction(UnaryMathFunction fun);
    824  AttachDecision tryAttachMathPow();
    825  AttachDecision tryAttachMathMinMax(bool isMax);
    826  AttachDecision tryAttachSpreadMathMinMax(bool isMax);
    827  AttachDecision tryAttachTypedArrayFill();
    828  AttachDecision tryAttachTypedArraySet();
    829  AttachDecision tryAttachTypedArraySubarray();
    830  AttachDecision tryAttachTypedArrayLength();
    831  AttachDecision tryAttachTypedArrayByteLength();
    832  AttachDecision tryAttachTypedArrayByteOffset();
    833  AttachDecision tryAttachIsTypedArray(bool isPossiblyWrapped);
    834  AttachDecision tryAttachIsTypedArrayConstructor();
    835  AttachDecision tryAttachTypedArrayLength(bool isPossiblyWrapped);
    836  AttachDecision tryAttachIsConstructing();
    837  AttachDecision tryAttachGetNextMapSetEntryForIterator(bool isMap);
    838  AttachDecision tryAttachNewArrayIterator();
    839  AttachDecision tryAttachNewStringIterator();
    840  AttachDecision tryAttachNewRegExpStringIterator();
    841  AttachDecision tryAttachArrayIteratorPrototypeOptimizable();
    842  AttachDecision tryAttachObjectCreate();
    843  AttachDecision tryAttachObjectConstructor();
    844  AttachDecision tryAttachArrayConstructor();
    845  AttachDecision tryAttachTypedArrayConstructor();
    846  AttachDecision tryAttachTypedArrayConstructorFromLength();
    847  AttachDecision tryAttachTypedArrayConstructorFromArrayBuffer();
    848  AttachDecision tryAttachTypedArrayConstructorFromArray();
    849  AttachDecision tryAttachMapSetConstructor(InlinableNative native);
    850  AttachDecision tryAttachNumber();
    851  AttachDecision tryAttachNumberParseInt();
    852  AttachDecision tryAttachNumberToString();
    853  AttachDecision tryAttachReflectGetPrototypeOf();
    854  AttachDecision tryAttachAtomicsCompareExchange();
    855  AttachDecision tryAttachAtomicsExchange();
    856  AttachDecision tryAttachAtomicsAdd();
    857  AttachDecision tryAttachAtomicsSub();
    858  AttachDecision tryAttachAtomicsAnd();
    859  AttachDecision tryAttachAtomicsOr();
    860  AttachDecision tryAttachAtomicsXor();
    861  AttachDecision tryAttachAtomicsLoad();
    862  AttachDecision tryAttachAtomicsStore();
    863  AttachDecision tryAttachAtomicsIsLockFree();
    864  AttachDecision tryAttachAtomicsPause();
    865  AttachDecision tryAttachBoolean();
    866  AttachDecision tryAttachBailout();
    867  AttachDecision tryAttachAssertFloat32();
    868  AttachDecision tryAttachAssertRecoveredOnBailout();
    869  AttachDecision tryAttachObjectIs();
    870  AttachDecision tryAttachObjectIsPrototypeOf();
    871  AttachDecision tryAttachObjectKeys();
    872  AttachDecision tryAttachObjectToString();
    873  AttachDecision tryAttachBigInt();
    874  AttachDecision tryAttachBigIntAsIntN();
    875  AttachDecision tryAttachBigIntAsUintN();
    876  AttachDecision tryAttachSetHas();
    877  AttachDecision tryAttachSetDelete();
    878  AttachDecision tryAttachSetAdd();
    879  AttachDecision tryAttachSetSize();
    880  AttachDecision tryAttachMapHas();
    881  AttachDecision tryAttachMapGet();
    882  AttachDecision tryAttachMapDelete();
    883  AttachDecision tryAttachMapSet();
    884  AttachDecision tryAttachMapSize();
    885  AttachDecision tryAttachDateGetTime();
    886  AttachDecision tryAttachDateGet(DateComponent component);
    887  AttachDecision tryAttachWeakMapHas();
    888  AttachDecision tryAttachWeakMapGet();
    889  AttachDecision tryAttachWeakSetHas();
    890  AttachDecision tryAttachArrayBufferByteLength();
    891  AttachDecision tryAttachSharedArrayBufferByteLength();
    892 #ifdef FUZZING_JS_FUZZILLI
    893  AttachDecision tryAttachFuzzilliHash();
    894 #endif
    895 
    896  void trackAttached(const char* name /* must be a C string literal */) {
    897    return gen_.match(
    898        [&](auto* generator) { return generator->trackAttached(name); });
    899  }
    900 
    901 public:
    902  InlinableNativeIRGenerator(CallIRGenerator& generator, HandleObject callee,
    903                             HandleFunction target, HandleValue newTarget,
    904                             HandleValue thisValue, HandleValueArray args,
    905                             CallFlags flags,
    906                             Handle<BoundFunctionObject*> boundTarget = nullptr)
    907      : gen_(&generator),
    908        generator_(generator),
    909        writer(generator.writer),
    910        cx_(generator.cx_),
    911        callee_(callee),
    912        target_(target),
    913        newTarget_(newTarget),
    914        thisval_(thisValue),
    915        args_(args),
    916        boundTarget_(boundTarget),
    917        flags_(flags),
    918        stackArgc_(generator.argc_),
    919        receiverId_() {}
    920 
    921  InlinableNativeIRGenerator(GetPropIRGenerator& generator,
    922                             HandleFunction target, HandleValue thisValue,
    923                             CallFlags flags, ValOperandId receiverId)
    924      : gen_(&generator),
    925        generator_(generator),
    926        writer(generator.writer),
    927        cx_(generator.cx_),
    928        callee_(target),
    929        target_(target),
    930        newTarget_(JS::NullHandleValue),
    931        thisval_(thisValue),
    932        args_(HandleValueArray::empty()),
    933        boundTarget_(nullptr),
    934        flags_(flags),
    935        stackArgc_(0),
    936        receiverId_(receiverId) {}
    937 
    938  AttachDecision tryAttachStub();
    939 };
    940 
    941 class MOZ_RAII CompareIRGenerator : public IRGenerator {
    942  JSOp op_;
    943  HandleValue lhsVal_;
    944  HandleValue rhsVal_;
    945 
    946  AttachDecision tryAttachString(ValOperandId lhsId, ValOperandId rhsId);
    947  AttachDecision tryAttachObject(ValOperandId lhsId, ValOperandId rhsId);
    948  AttachDecision tryAttachSymbol(ValOperandId lhsId, ValOperandId rhsId);
    949  AttachDecision tryAttachStrictDifferentTypes(ValOperandId lhsId,
    950                                               ValOperandId rhsId);
    951  AttachDecision tryAttachInt32(ValOperandId lhsId, ValOperandId rhsId);
    952  AttachDecision tryAttachNumber(ValOperandId lhsId, ValOperandId rhsId);
    953  AttachDecision tryAttachBigInt(ValOperandId lhsId, ValOperandId rhsId);
    954  AttachDecision tryAttachAnyNullUndefined(ValOperandId lhsId,
    955                                           ValOperandId rhsId);
    956  AttachDecision tryAttachNullUndefined(ValOperandId lhsId, ValOperandId rhsId);
    957  AttachDecision tryAttachStringNumber(ValOperandId lhsId, ValOperandId rhsId);
    958  AttachDecision tryAttachPrimitiveSymbol(ValOperandId lhsId,
    959                                          ValOperandId rhsId);
    960  AttachDecision tryAttachBigIntInt32(ValOperandId lhsId, ValOperandId rhsId);
    961  AttachDecision tryAttachBigIntNumber(ValOperandId lhsId, ValOperandId rhsId);
    962  AttachDecision tryAttachBigIntString(ValOperandId lhsId, ValOperandId rhsId);
    963 
    964  void trackAttached(const char* name /* must be a C string literal */);
    965 
    966 public:
    967  CompareIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState state,
    968                     JSOp op, HandleValue lhsVal, HandleValue rhsVal);
    969 
    970  AttachDecision tryAttachStub();
    971 };
    972 
    973 class MOZ_RAII ToBoolIRGenerator : public IRGenerator {
    974  HandleValue val_;
    975 
    976  AttachDecision tryAttachBool();
    977  AttachDecision tryAttachInt32();
    978  AttachDecision tryAttachNumber();
    979  AttachDecision tryAttachString();
    980  AttachDecision tryAttachSymbol();
    981  AttachDecision tryAttachNullOrUndefined();
    982  AttachDecision tryAttachObject();
    983  AttachDecision tryAttachBigInt();
    984 
    985  void trackAttached(const char* name /* must be a C string literal */);
    986 
    987 public:
    988  ToBoolIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState state,
    989                    HandleValue val);
    990 
    991  AttachDecision tryAttachStub();
    992 };
    993 
    994 class MOZ_RAII LazyConstantIRGenerator : public IRGenerator {
    995  HandleValue val_;
    996 
    997  void trackAttached(const char* name /* must be a C string literal */);
    998 
    999 public:
   1000  LazyConstantIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
   1001                          ICState state, HandleValue val);
   1002 
   1003  AttachDecision tryAttachStub();
   1004 };
   1005 
   1006 class MOZ_RAII UnaryArithIRGenerator : public IRGenerator {
   1007  JSOp op_;
   1008  HandleValue val_;
   1009  HandleValue res_;
   1010 
   1011  AttachDecision tryAttachInt32();
   1012  AttachDecision tryAttachNumber();
   1013  AttachDecision tryAttachBitwise();
   1014  AttachDecision tryAttachBigInt();
   1015  AttachDecision tryAttachBigIntPtr();
   1016  AttachDecision tryAttachStringInt32();
   1017  AttachDecision tryAttachStringNumber();
   1018 
   1019  void trackAttached(const char* name /* must be a C string literal */);
   1020 
   1021 public:
   1022  UnaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
   1023                        ICState state, JSOp op, HandleValue val,
   1024                        HandleValue res);
   1025 
   1026  AttachDecision tryAttachStub();
   1027 };
   1028 
   1029 class MOZ_RAII ToPropertyKeyIRGenerator : public IRGenerator {
   1030  HandleValue val_;
   1031 
   1032  AttachDecision tryAttachInt32();
   1033  AttachDecision tryAttachNumber();
   1034  AttachDecision tryAttachString();
   1035  AttachDecision tryAttachSymbol();
   1036 
   1037  void trackAttached(const char* name /* must be a C string literal */);
   1038 
   1039 public:
   1040  ToPropertyKeyIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
   1041                           ICState state, HandleValue val);
   1042 
   1043  AttachDecision tryAttachStub();
   1044 };
   1045 
   1046 class MOZ_RAII BinaryArithIRGenerator : public IRGenerator {
   1047  JSOp op_;
   1048  HandleValue lhs_;
   1049  HandleValue rhs_;
   1050  HandleValue res_;
   1051 
   1052  void trackAttached(const char* name /* must be a C string literal */);
   1053 
   1054  AttachDecision tryAttachInt32();
   1055  AttachDecision tryAttachDouble();
   1056  AttachDecision tryAttachBitwise();
   1057  AttachDecision tryAttachStringConcat();
   1058  AttachDecision tryAttachStringObjectConcat();
   1059  AttachDecision tryAttachBigInt();
   1060  AttachDecision tryAttachBigIntPtr();
   1061  AttachDecision tryAttachStringInt32Arith();
   1062  AttachDecision tryAttachStringNumberArith();
   1063  AttachDecision tryAttachDateArith();
   1064 
   1065 public:
   1066  BinaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
   1067                         ICState state, JSOp op, HandleValue lhs,
   1068                         HandleValue rhs, HandleValue res);
   1069 
   1070  AttachDecision tryAttachStub();
   1071 };
   1072 
   1073 class MOZ_RAII NewArrayIRGenerator : public IRGenerator {
   1074 #ifdef JS_CACHEIR_SPEW
   1075  JSOp op_;
   1076 #endif
   1077  HandleObject templateObject_;
   1078 
   1079  void trackAttached(const char* name /* must be a C string literal */);
   1080 
   1081 public:
   1082  NewArrayIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
   1083                      ICState state, JSOp op, HandleObject templateObj,
   1084                      BaselineFrame* frame);
   1085 
   1086  AttachDecision tryAttachStub();
   1087  AttachDecision tryAttachArrayObject();
   1088 };
   1089 
   1090 class MOZ_RAII NewObjectIRGenerator : public IRGenerator {
   1091 #ifdef JS_CACHEIR_SPEW
   1092  JSOp op_;
   1093 #endif
   1094  HandleObject templateObject_;
   1095 
   1096  void trackAttached(const char* name /* must be a C string literal */);
   1097 
   1098 public:
   1099  NewObjectIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
   1100                       ICState state, JSOp op, HandleObject templateObj,
   1101                       BaselineFrame* frame);
   1102 
   1103  AttachDecision tryAttachStub();
   1104  AttachDecision tryAttachPlainObject();
   1105 };
   1106 
   1107 class MOZ_RAII LambdaIRGenerator : public IRGenerator {
   1108 #ifdef JS_CACHEIR_SPEW
   1109  JSOp op_;
   1110 #endif
   1111  Handle<JSFunction*> canonicalFunction_;
   1112 
   1113  void trackAttached(const char* name /* must be a C string literal */);
   1114 
   1115 public:
   1116  LambdaIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
   1117                    ICState state, JSOp op,
   1118                    Handle<JSFunction*> canonicalFunction,
   1119                    BaselineFrame* frame);
   1120 
   1121  AttachDecision tryAttachStub();
   1122  AttachDecision tryAttachFunctionClone();
   1123 };
   1124 
   1125 // Returns true for bytecode call ops that can use InlinableNativeIRGenerator.
   1126 inline bool BytecodeCallOpCanHaveInlinableNative(JSOp op) {
   1127  return op == JSOp::Call || op == JSOp::CallContent || op == JSOp::New ||
   1128         op == JSOp::NewContent || op == JSOp::CallIgnoresRv ||
   1129         op == JSOp::SpreadCall;
   1130 }
   1131 
   1132 // Returns true for bytecode get ops that can use InlinableNativeIRGenerator.
   1133 inline bool BytecodeGetOpCanHaveInlinableNative(JSOp op) {
   1134  return op == JSOp::GetProp || op == JSOp::GetElem ||
   1135         op == JSOp::GetPropSuper || op == JSOp::GetElemSuper;
   1136 }
   1137 
   1138 inline bool BytecodeOpCanHaveAllocSite(JSOp op) {
   1139  return BytecodeCallOpCanHaveInlinableNative(op) || op == JSOp::NewArray ||
   1140         op == JSOp::NewObject || op == JSOp::NewInit || op == JSOp::CallIter ||
   1141         op == JSOp::CallContentIter || op == JSOp::Lambda;
   1142 }
   1143 
   1144 class MOZ_RAII CloseIterIRGenerator : public IRGenerator {
   1145  HandleObject iter_;
   1146  CompletionKind kind_;
   1147 
   1148  void trackAttached(const char* name /* must be a C string literal */);
   1149 
   1150 public:
   1151  CloseIterIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc,
   1152                       ICState state, HandleObject iter, CompletionKind kind);
   1153 
   1154  AttachDecision tryAttachStub();
   1155  AttachDecision tryAttachNoReturnMethod();
   1156  AttachDecision tryAttachScriptedReturn();
   1157 };
   1158 
   1159 class MOZ_RAII GetImportIRGenerator : public IRGenerator {
   1160  void trackAttached(const char* name /* must be a C string literal */);
   1161 
   1162 public:
   1163  GetImportIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc,
   1164                       ICState state);
   1165 
   1166  AttachDecision tryAttachStub();
   1167  AttachDecision tryAttachInitialized();
   1168 };
   1169 
   1170 // Retrieve Xray JIT info set by the embedder.
   1171 extern JS::XrayJitInfo* GetXrayJitInfo();
   1172 
   1173 }  // namespace jit
   1174 }  // namespace js
   1175 
   1176 #endif /* jit_CacheIRGenerator_h */