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 */