diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /js/src/jit/CacheIRGenerator.h | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | js/src/jit/CacheIRGenerator.h | 912 |
1 files changed, 912 insertions, 0 deletions
diff --git a/js/src/jit/CacheIRGenerator.h b/js/src/jit/CacheIRGenerator.h new file mode 100644 index 0000000000..9d1439a434 --- /dev/null +++ b/js/src/jit/CacheIRGenerator.h @@ -0,0 +1,912 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef jit_CacheIRGenerator_h +#define jit_CacheIRGenerator_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/Maybe.h" + +#include <stdint.h> + +#include "jstypes.h" +#include "NamespaceImports.h" + +#include "jit/CacheIR.h" +#include "jit/CacheIRWriter.h" +#include "jit/ICState.h" +#include "js/Id.h" +#include "js/RootingAPI.h" +#include "js/ScalarType.h" +#include "js/TypeDecls.h" +#include "js/Value.h" +#include "js/ValueArray.h" +#include "vm/Opcodes.h" + +class JSFunction; + +namespace JS { +struct XrayJitInfo; +} + +namespace js { + +class BoundFunctionObject; +class NativeObject; +class PropertyResult; +class ProxyObject; +enum class UnaryMathFunction : uint8_t; + +namespace jit { + +class BaselineFrame; +class Label; +class MacroAssembler; +struct Register; +enum class InlinableNative : uint16_t; + +// Some ops refer to shapes that might be in other zones. Instead of putting +// cross-zone pointers in the caches themselves (which would complicate tracing +// enormously), these ops instead contain wrappers for objects in the target +// zone, which refer to the actual shape via a reserved slot. +void LoadShapeWrapperContents(MacroAssembler& masm, Register obj, Register dst, + Label* failure); + +class MOZ_RAII IRGenerator { + protected: + CacheIRWriter writer; + JSContext* cx_; + HandleScript script_; + jsbytecode* pc_; + CacheKind cacheKind_; + ICState::Mode mode_; + bool isFirstStub_; + + // Important: This pointer may be passed to the profiler. If this is non-null, + // it must point to a C string literal with static lifetime, not a heap- or + // stack- allocated string. + const char* stubName_ = nullptr; + + IRGenerator(const IRGenerator&) = delete; + IRGenerator& operator=(const IRGenerator&) = delete; + + bool maybeGuardInt32Index(const Value& index, ValOperandId indexId, + uint32_t* int32Index, Int32OperandId* int32IndexId); + + IntPtrOperandId guardToIntPtrIndex(const Value& index, ValOperandId indexId, + bool supportOOB); + + ObjOperandId guardDOMProxyExpandoObjectAndShape(ProxyObject* obj, + ObjOperandId objId, + const Value& expandoVal, + NativeObject* expandoObj); + + void emitIdGuard(ValOperandId valId, const Value& idVal, jsid id); + + OperandId emitNumericGuard(ValOperandId valId, Scalar::Type type); + + StringOperandId emitToStringGuard(ValOperandId id, const Value& v); + + void emitCalleeGuard(ObjOperandId calleeId, JSFunction* callee); + + void emitOptimisticClassGuard(ObjOperandId objId, JSObject* obj, + GuardClassKind kind); + + friend class CacheIRSpewer; + + public: + explicit IRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, + CacheKind cacheKind, ICState state); + + const CacheIRWriter& writerRef() const { return writer; } + CacheKind cacheKind() const { return cacheKind_; } + + // See comment on `stubName_` above. + const char* stubName() const { return stubName_; } + + static constexpr char* NotAttached = nullptr; +}; + +// GetPropIRGenerator generates CacheIR for a GetProp IC. +class MOZ_RAII GetPropIRGenerator : public IRGenerator { + HandleValue val_; + HandleValue idVal_; + + AttachDecision tryAttachNative(HandleObject obj, ObjOperandId objId, + HandleId id, ValOperandId receiverId); + AttachDecision tryAttachObjectLength(HandleObject obj, ObjOperandId objId, + HandleId id); + AttachDecision tryAttachTypedArray(HandleObject obj, ObjOperandId objId, + HandleId id); + AttachDecision tryAttachDataView(HandleObject obj, ObjOperandId objId, + HandleId id); + AttachDecision tryAttachArrayBufferMaybeShared(HandleObject obj, + ObjOperandId objId, + HandleId id); + AttachDecision tryAttachRegExp(HandleObject obj, ObjOperandId objId, + HandleId id); + AttachDecision tryAttachMap(HandleObject obj, ObjOperandId objId, + HandleId id); + AttachDecision tryAttachSet(HandleObject obj, ObjOperandId objId, + HandleId id); + AttachDecision tryAttachModuleNamespace(HandleObject obj, ObjOperandId objId, + HandleId id); + AttachDecision tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, + HandleId id); + AttachDecision tryAttachCrossCompartmentWrapper(HandleObject obj, + ObjOperandId objId, + HandleId id); + AttachDecision tryAttachXrayCrossCompartmentWrapper(HandleObject obj, + ObjOperandId objId, + HandleId id, + ValOperandId receiverId); + AttachDecision tryAttachFunction(HandleObject obj, ObjOperandId objId, + HandleId id); + AttachDecision tryAttachArgumentsObjectIterator(HandleObject obj, + ObjOperandId objId, + HandleId id); + + AttachDecision tryAttachGenericProxy(Handle<ProxyObject*> obj, + ObjOperandId objId, HandleId id, + bool handleDOMProxies); + AttachDecision tryAttachDOMProxyExpando(Handle<ProxyObject*> obj, + ObjOperandId objId, HandleId id, + ValOperandId receiverId); + AttachDecision tryAttachDOMProxyShadowed(Handle<ProxyObject*> obj, + ObjOperandId objId, HandleId id); + AttachDecision tryAttachDOMProxyUnshadowed(Handle<ProxyObject*> obj, + ObjOperandId objId, HandleId id, + ValOperandId receiverId); + AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId, + HandleId id, ValOperandId receiverId); + + AttachDecision tryAttachPrimitive(ValOperandId valId, HandleId id); + AttachDecision tryAttachStringChar(ValOperandId valId, ValOperandId indexId); + AttachDecision tryAttachStringLength(ValOperandId valId, HandleId id); + + AttachDecision tryAttachArgumentsObjectArg(HandleObject obj, + ObjOperandId objId, uint32_t index, + Int32OperandId indexId); + AttachDecision tryAttachArgumentsObjectArgHole(HandleObject obj, + ObjOperandId objId, + uint32_t index, + Int32OperandId indexId); + AttachDecision tryAttachArgumentsObjectCallee(HandleObject obj, + ObjOperandId objId, + HandleId id); + + AttachDecision tryAttachDenseElement(HandleObject obj, ObjOperandId objId, + uint32_t index, Int32OperandId indexId); + AttachDecision tryAttachDenseElementHole(HandleObject obj, ObjOperandId objId, + uint32_t index, + Int32OperandId indexId); + AttachDecision tryAttachSparseElement(HandleObject obj, ObjOperandId objId, + uint32_t index, Int32OperandId indexId); + AttachDecision tryAttachTypedArrayElement(HandleObject obj, + ObjOperandId objId); + + AttachDecision tryAttachGenericElement(HandleObject obj, ObjOperandId objId, + uint32_t index, Int32OperandId indexId, + ValOperandId receiverId); + + AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId); + + void attachMegamorphicNativeSlot(ObjOperandId objId, jsid id); + + ValOperandId getElemKeyValueId() const { + MOZ_ASSERT(cacheKind_ == CacheKind::GetElem || + cacheKind_ == CacheKind::GetElemSuper); + return ValOperandId(1); + } + + ValOperandId getSuperReceiverValueId() const { + if (cacheKind_ == CacheKind::GetPropSuper) { + return ValOperandId(1); + } + + MOZ_ASSERT(cacheKind_ == CacheKind::GetElemSuper); + return ValOperandId(2); + } + + bool isSuper() const { + return (cacheKind_ == CacheKind::GetPropSuper || + cacheKind_ == CacheKind::GetElemSuper); + } + + // If this is a GetElem cache, emit instructions to guard the incoming Value + // matches |id|. + void maybeEmitIdGuard(jsid id); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + GetPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, + ICState state, CacheKind cacheKind, HandleValue val, + HandleValue idVal); + + AttachDecision tryAttachStub(); +}; + +// GetNameIRGenerator generates CacheIR for a GetName IC. +class MOZ_RAII GetNameIRGenerator : public IRGenerator { + HandleObject env_; + Handle<PropertyName*> name_; + + AttachDecision tryAttachGlobalNameValue(ObjOperandId objId, HandleId id); + AttachDecision tryAttachGlobalNameGetter(ObjOperandId objId, HandleId id); + AttachDecision tryAttachEnvironmentName(ObjOperandId objId, HandleId id); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + GetNameIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, + ICState state, HandleObject env, + Handle<PropertyName*> name); + + AttachDecision tryAttachStub(); +}; + +// BindNameIRGenerator generates CacheIR for a BindName IC. +class MOZ_RAII BindNameIRGenerator : public IRGenerator { + HandleObject env_; + Handle<PropertyName*> name_; + + AttachDecision tryAttachGlobalName(ObjOperandId objId, HandleId id); + AttachDecision tryAttachEnvironmentName(ObjOperandId objId, HandleId id); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + BindNameIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, + ICState state, HandleObject env, + Handle<PropertyName*> name); + + AttachDecision tryAttachStub(); +}; + +// SetPropIRGenerator generates CacheIR for a SetProp IC. +class MOZ_RAII SetPropIRGenerator : public IRGenerator { + HandleValue lhsVal_; + HandleValue idVal_; + HandleValue rhsVal_; + + public: + enum class DeferType { None, AddSlot }; + + private: + DeferType deferType_ = DeferType::None; + + ValOperandId setElemKeyValueId() const { + MOZ_ASSERT(cacheKind_ == CacheKind::SetElem); + return ValOperandId(1); + } + + ValOperandId rhsValueId() const { + if (cacheKind_ == CacheKind::SetProp) { + return ValOperandId(1); + } + MOZ_ASSERT(cacheKind_ == CacheKind::SetElem); + return ValOperandId(2); + } + + // If this is a SetElem cache, emit instructions to guard the incoming Value + // matches |id|. + void maybeEmitIdGuard(jsid id); + + AttachDecision tryAttachNativeSetSlot(HandleObject obj, ObjOperandId objId, + HandleId id, ValOperandId rhsId); + AttachDecision tryAttachMegamorphicSetSlot(HandleObject obj, + ObjOperandId objId, HandleId id, + ValOperandId rhsId); + AttachDecision tryAttachSetter(HandleObject obj, ObjOperandId objId, + HandleId id, ValOperandId rhsId); + AttachDecision tryAttachSetArrayLength(HandleObject obj, ObjOperandId objId, + HandleId id, ValOperandId rhsId); + AttachDecision tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, + HandleId id, ValOperandId rhsId); + + AttachDecision tryAttachSetDenseElement(HandleObject obj, ObjOperandId objId, + uint32_t index, + Int32OperandId indexId, + ValOperandId rhsId); + AttachDecision tryAttachSetTypedArrayElement(HandleObject obj, + ObjOperandId objId, + ValOperandId rhsId); + + AttachDecision tryAttachSetDenseElementHole(HandleObject obj, + ObjOperandId objId, + uint32_t index, + Int32OperandId indexId, + ValOperandId rhsId); + + AttachDecision tryAttachAddOrUpdateSparseElement(HandleObject obj, + ObjOperandId objId, + uint32_t index, + Int32OperandId indexId, + ValOperandId rhsId); + + AttachDecision tryAttachGenericProxy(Handle<ProxyObject*> obj, + ObjOperandId objId, HandleId id, + ValOperandId rhsId, + bool handleDOMProxies); + AttachDecision tryAttachDOMProxyShadowed(Handle<ProxyObject*> obj, + ObjOperandId objId, HandleId id, + ValOperandId rhsId); + AttachDecision tryAttachDOMProxyUnshadowed(Handle<ProxyObject*> obj, + ObjOperandId objId, HandleId id, + ValOperandId rhsId); + AttachDecision tryAttachDOMProxyExpando(Handle<ProxyObject*> obj, + ObjOperandId objId, HandleId id, + ValOperandId rhsId); + AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId, + HandleId id, ValOperandId rhsId); + AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId, + ValOperandId rhsId); + AttachDecision tryAttachMegamorphicSetElement(HandleObject obj, + ObjOperandId objId, + ValOperandId rhsId); + + bool canAttachAddSlotStub(HandleObject obj, HandleId id); + + public: + SetPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, + CacheKind cacheKind, ICState state, HandleValue lhsVal, + HandleValue idVal, HandleValue rhsVal); + + AttachDecision tryAttachStub(); + AttachDecision tryAttachAddSlotStub(Handle<Shape*> oldShape); + void trackAttached(const char* name /* must be a C string literal */); + + DeferType deferType() const { return deferType_; } +}; + +// HasPropIRGenerator generates CacheIR for a HasProp IC. Used for +// CacheKind::In / CacheKind::HasOwn. +class MOZ_RAII HasPropIRGenerator : public IRGenerator { + HandleValue val_; + HandleValue idVal_; + + AttachDecision tryAttachDense(HandleObject obj, ObjOperandId objId, + uint32_t index, Int32OperandId indexId); + AttachDecision tryAttachDenseHole(HandleObject obj, ObjOperandId objId, + uint32_t index, Int32OperandId indexId); + AttachDecision tryAttachTypedArray(HandleObject obj, ObjOperandId objId, + ValOperandId keyId); + AttachDecision tryAttachSparse(HandleObject obj, ObjOperandId objId, + Int32OperandId indexId); + AttachDecision tryAttachArgumentsObjectArg(HandleObject obj, + ObjOperandId objId, + Int32OperandId indexId); + AttachDecision tryAttachNamedProp(HandleObject obj, ObjOperandId objId, + HandleId key, ValOperandId keyId); + AttachDecision tryAttachMegamorphic(ObjOperandId objId, ValOperandId keyId); + AttachDecision tryAttachNative(NativeObject* obj, ObjOperandId objId, + jsid key, ValOperandId keyId, + PropertyResult prop, NativeObject* holder); + AttachDecision tryAttachSlotDoesNotExist(NativeObject* obj, + ObjOperandId objId, jsid key, + ValOperandId keyId); + AttachDecision tryAttachDoesNotExist(HandleObject obj, ObjOperandId objId, + HandleId key, ValOperandId keyId); + AttachDecision tryAttachProxyElement(HandleObject obj, ObjOperandId objId, + ValOperandId keyId); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + // NOTE: Argument order is PROPERTY, OBJECT + HasPropIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, + ICState state, CacheKind cacheKind, HandleValue idVal, + HandleValue val); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII CheckPrivateFieldIRGenerator : public IRGenerator { + HandleValue val_; + HandleValue idVal_; + + AttachDecision tryAttachNative(NativeObject* obj, ObjOperandId objId, + jsid key, ValOperandId keyId, + PropertyResult prop); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + CheckPrivateFieldIRGenerator(JSContext* cx, HandleScript script, + jsbytecode* pc, ICState state, + CacheKind cacheKind, HandleValue idVal, + HandleValue val); + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII InstanceOfIRGenerator : public IRGenerator { + HandleValue lhsVal_; + HandleObject rhsObj_; + + void trackAttached(const char* name /* must be a C string literal */); + + public: + InstanceOfIRGenerator(JSContext*, HandleScript, jsbytecode*, ICState, + HandleValue, HandleObject); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII TypeOfIRGenerator : public IRGenerator { + HandleValue val_; + + AttachDecision tryAttachPrimitive(ValOperandId valId); + AttachDecision tryAttachObject(ValOperandId valId); + void trackAttached(const char* name /* must be a C string literal */); + + public: + TypeOfIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState state, + HandleValue value); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII GetIteratorIRGenerator : public IRGenerator { + HandleValue val_; + + AttachDecision tryAttachObject(ValOperandId valId); + AttachDecision tryAttachNullOrUndefined(ValOperandId valId); + AttachDecision tryAttachGeneric(ValOperandId valId); + + public: + GetIteratorIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, + ICState state, HandleValue value); + + AttachDecision tryAttachStub(); + + void trackAttached(const char* name /* must be a C string literal */); +}; + +class MOZ_RAII OptimizeSpreadCallIRGenerator : public IRGenerator { + HandleValue val_; + + AttachDecision tryAttachArray(); + AttachDecision tryAttachArguments(); + AttachDecision tryAttachNotOptimizable(); + + public: + OptimizeSpreadCallIRGenerator(JSContext* cx, HandleScript script, + jsbytecode* pc, ICState state, + HandleValue value); + + AttachDecision tryAttachStub(); + + void trackAttached(const char* name /* must be a C string literal */); +}; + +enum class StringChar { CodeAt, At }; +enum class ScriptedThisResult { NoAction, UninitializedThis, PlainObjectShape }; + +class MOZ_RAII CallIRGenerator : public IRGenerator { + private: + JSOp op_; + uint32_t argc_; + HandleValue callee_; + HandleValue thisval_; + HandleValue newTarget_; + HandleValueArray args_; + + friend class InlinableNativeIRGenerator; + + ScriptedThisResult getThisShapeForScripted(HandleFunction calleeFunc, + Handle<JSObject*> newTarget, + MutableHandle<Shape*> result); + + ObjOperandId emitFunCallOrApplyGuard(Int32OperandId argcId); + ObjOperandId emitFunCallGuard(Int32OperandId argcId); + ObjOperandId emitFunApplyGuard(Int32OperandId argcId); + mozilla::Maybe<ObjOperandId> emitFunApplyArgsGuard( + CallFlags::ArgFormat format); + + void emitCallScriptedGuards(ObjOperandId calleeObjId, JSFunction* calleeFunc, + Int32OperandId argcId, CallFlags flags, + Shape* thisShape, bool isBoundFunction); + + AttachDecision tryAttachFunCall(HandleFunction calleeFunc); + AttachDecision tryAttachFunApply(HandleFunction calleeFunc); + AttachDecision tryAttachCallScripted(HandleFunction calleeFunc); + AttachDecision tryAttachInlinableNative(HandleFunction calleeFunc, + CallFlags flags); + AttachDecision tryAttachWasmCall(HandleFunction calleeFunc); + AttachDecision tryAttachCallNative(HandleFunction calleeFunc); + AttachDecision tryAttachCallHook(HandleObject calleeObj); + AttachDecision tryAttachBoundFunction(Handle<BoundFunctionObject*> calleeObj); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + CallIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, JSOp op, + ICState state, uint32_t argc, HandleValue callee, + HandleValue thisval, HandleValue newTarget, + HandleValueArray args); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII InlinableNativeIRGenerator { + CallIRGenerator& generator_; + CacheIRWriter& writer; + JSContext* cx_; + + HandleFunction callee_; + HandleValue newTarget_; + HandleValue thisval_; + HandleValueArray args_; + uint32_t argc_; + CallFlags flags_; + + HandleScript script() const { return generator_.script_; } + bool isFirstStub() const { return generator_.isFirstStub_; } + bool ignoresResult() const { return generator_.op_ == JSOp::CallIgnoresRv; } + + void emitNativeCalleeGuard(); + void emitOptimisticClassGuard(ObjOperandId objId, JSObject* obj, + GuardClassKind kind) { + generator_.emitOptimisticClassGuard(objId, obj, kind); + } + + ObjOperandId emitLoadArgsArray(); + + void initializeInputOperand() { + // The input operand is already initialized for FunCall and FunApplyArray. + if (flags_.getArgFormat() == CallFlags::FunCall || + flags_.getArgFormat() == CallFlags::FunApplyArray) { + return; + } + (void)writer.setInputOperandId(0); + } + + auto emitToStringGuard(ValOperandId id, const Value& v) { + return generator_.emitToStringGuard(id, v); + } + + auto emitNumericGuard(ValOperandId valId, Scalar::Type type) { + return generator_.emitNumericGuard(valId, type); + } + + auto guardToIntPtrIndex(const Value& index, ValOperandId indexId, + bool supportOOB) { + return generator_.guardToIntPtrIndex(index, indexId, supportOOB); + } + + bool canAttachAtomicsReadWriteModify(); + + struct AtomicsReadWriteModifyOperands { + ObjOperandId objId; + IntPtrOperandId intPtrIndexId; + OperandId numericValueId; + }; + + AtomicsReadWriteModifyOperands emitAtomicsReadWriteModifyOperands(); + + AttachDecision tryAttachArrayPush(); + AttachDecision tryAttachArrayPopShift(InlinableNative native); + AttachDecision tryAttachArrayJoin(); + AttachDecision tryAttachArraySlice(); + AttachDecision tryAttachArrayIsArray(); + AttachDecision tryAttachDataViewGet(Scalar::Type type); + AttachDecision tryAttachDataViewSet(Scalar::Type type); + AttachDecision tryAttachFunctionBind(); + AttachDecision tryAttachSpecializedFunctionBind( + Handle<JSObject*> target, Handle<BoundFunctionObject*> templateObj); + AttachDecision tryAttachUnsafeGetReservedSlot(InlinableNative native); + AttachDecision tryAttachUnsafeSetReservedSlot(); + AttachDecision tryAttachIsSuspendedGenerator(); + AttachDecision tryAttachToObject(); + AttachDecision tryAttachToInteger(); + AttachDecision tryAttachToLength(); + AttachDecision tryAttachIsObject(); + AttachDecision tryAttachIsPackedArray(); + AttachDecision tryAttachIsCallable(); + AttachDecision tryAttachIsConstructor(); + AttachDecision tryAttachIsCrossRealmArrayConstructor(); + AttachDecision tryAttachGuardToClass(InlinableNative native); + AttachDecision tryAttachHasClass(const JSClass* clasp, + bool isPossiblyWrapped); + AttachDecision tryAttachRegExpMatcherSearcher(InlinableNative native); + AttachDecision tryAttachRegExpPrototypeOptimizable(); + AttachDecision tryAttachRegExpInstanceOptimizable(); + AttachDecision tryAttachIntrinsicRegExpBuiltinExec(InlinableNative native); + AttachDecision tryAttachIntrinsicRegExpExec(InlinableNative native); + AttachDecision tryAttachGetFirstDollarIndex(); + AttachDecision tryAttachSubstringKernel(); + AttachDecision tryAttachObjectHasPrototype(); + AttachDecision tryAttachString(); + AttachDecision tryAttachStringConstructor(); + AttachDecision tryAttachStringToStringValueOf(); + AttachDecision tryAttachStringChar(StringChar kind); + AttachDecision tryAttachStringCharCodeAt(); + AttachDecision tryAttachStringCharAt(); + AttachDecision tryAttachStringFromCharCode(); + AttachDecision tryAttachStringFromCodePoint(); + AttachDecision tryAttachStringIndexOf(); + AttachDecision tryAttachStringStartsWith(); + AttachDecision tryAttachStringEndsWith(); + AttachDecision tryAttachStringToLowerCase(); + AttachDecision tryAttachStringToUpperCase(); + AttachDecision tryAttachStringReplaceString(); + AttachDecision tryAttachStringSplitString(); + AttachDecision tryAttachMathRandom(); + AttachDecision tryAttachMathAbs(); + AttachDecision tryAttachMathClz32(); + AttachDecision tryAttachMathSign(); + AttachDecision tryAttachMathImul(); + AttachDecision tryAttachMathFloor(); + AttachDecision tryAttachMathCeil(); + AttachDecision tryAttachMathTrunc(); + AttachDecision tryAttachMathRound(); + AttachDecision tryAttachMathSqrt(); + AttachDecision tryAttachMathFRound(); + AttachDecision tryAttachMathHypot(); + AttachDecision tryAttachMathATan2(); + AttachDecision tryAttachMathFunction(UnaryMathFunction fun); + AttachDecision tryAttachMathPow(); + AttachDecision tryAttachMathMinMax(bool isMax); + AttachDecision tryAttachSpreadMathMinMax(bool isMax); + AttachDecision tryAttachIsTypedArray(bool isPossiblyWrapped); + AttachDecision tryAttachIsTypedArrayConstructor(); + AttachDecision tryAttachTypedArrayByteOffset(); + AttachDecision tryAttachTypedArrayElementSize(); + AttachDecision tryAttachTypedArrayLength(bool isPossiblyWrapped); + AttachDecision tryAttachArrayBufferByteLength(bool isPossiblyWrapped); + AttachDecision tryAttachIsConstructing(); + AttachDecision tryAttachGetNextMapSetEntryForIterator(bool isMap); + AttachDecision tryAttachNewArrayIterator(); + AttachDecision tryAttachNewStringIterator(); + AttachDecision tryAttachNewRegExpStringIterator(); + AttachDecision tryAttachArrayIteratorPrototypeOptimizable(); + AttachDecision tryAttachObjectCreate(); + AttachDecision tryAttachObjectConstructor(); + AttachDecision tryAttachArrayConstructor(); + AttachDecision tryAttachTypedArrayConstructor(); + AttachDecision tryAttachNumber(); + AttachDecision tryAttachNumberParseInt(); + AttachDecision tryAttachNumberToString(); + AttachDecision tryAttachReflectGetPrototypeOf(); + AttachDecision tryAttachAtomicsCompareExchange(); + AttachDecision tryAttachAtomicsExchange(); + AttachDecision tryAttachAtomicsAdd(); + AttachDecision tryAttachAtomicsSub(); + AttachDecision tryAttachAtomicsAnd(); + AttachDecision tryAttachAtomicsOr(); + AttachDecision tryAttachAtomicsXor(); + AttachDecision tryAttachAtomicsLoad(); + AttachDecision tryAttachAtomicsStore(); + AttachDecision tryAttachAtomicsIsLockFree(); + AttachDecision tryAttachBoolean(); + AttachDecision tryAttachBailout(); + AttachDecision tryAttachAssertFloat32(); + AttachDecision tryAttachAssertRecoveredOnBailout(); + AttachDecision tryAttachObjectIs(); + AttachDecision tryAttachObjectIsPrototypeOf(); + AttachDecision tryAttachObjectToString(); + AttachDecision tryAttachBigIntAsIntN(); + AttachDecision tryAttachBigIntAsUintN(); + AttachDecision tryAttachSetHas(); + AttachDecision tryAttachMapHas(); + AttachDecision tryAttachMapGet(); +#ifdef FUZZING_JS_FUZZILLI + AttachDecision tryAttachFuzzilliHash(); +#endif + + void trackAttached(const char* name /* must be a C string literal */) { + return generator_.trackAttached(name); + } + + public: + InlinableNativeIRGenerator(CallIRGenerator& generator, HandleFunction callee, + HandleValue newTarget, HandleValue thisValue, + HandleValueArray args, CallFlags flags) + : generator_(generator), + writer(generator.writer), + cx_(generator.cx_), + callee_(callee), + newTarget_(newTarget), + thisval_(thisValue), + args_(args), + argc_(args.length()), + flags_(flags) {} + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII CompareIRGenerator : public IRGenerator { + JSOp op_; + HandleValue lhsVal_; + HandleValue rhsVal_; + + AttachDecision tryAttachString(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachObject(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachSymbol(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachStrictDifferentTypes(ValOperandId lhsId, + ValOperandId rhsId); + AttachDecision tryAttachInt32(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachNumber(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachBigInt(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachAnyNullUndefined(ValOperandId lhsId, + ValOperandId rhsId); + AttachDecision tryAttachNullUndefined(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachStringNumber(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachPrimitiveSymbol(ValOperandId lhsId, + ValOperandId rhsId); + AttachDecision tryAttachBigIntInt32(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachBigIntNumber(ValOperandId lhsId, ValOperandId rhsId); + AttachDecision tryAttachBigIntString(ValOperandId lhsId, ValOperandId rhsId); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + CompareIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState state, + JSOp op, HandleValue lhsVal, HandleValue rhsVal); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII ToBoolIRGenerator : public IRGenerator { + HandleValue val_; + + AttachDecision tryAttachBool(); + AttachDecision tryAttachInt32(); + AttachDecision tryAttachNumber(); + AttachDecision tryAttachString(); + AttachDecision tryAttachSymbol(); + AttachDecision tryAttachNullOrUndefined(); + AttachDecision tryAttachObject(); + AttachDecision tryAttachBigInt(); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + ToBoolIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, ICState state, + HandleValue val); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII GetIntrinsicIRGenerator : public IRGenerator { + HandleValue val_; + + void trackAttached(const char* name /* must be a C string literal */); + + public: + GetIntrinsicIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, + ICState state, HandleValue val); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII UnaryArithIRGenerator : public IRGenerator { + JSOp op_; + HandleValue val_; + HandleValue res_; + + AttachDecision tryAttachInt32(); + AttachDecision tryAttachNumber(); + AttachDecision tryAttachBitwise(); + AttachDecision tryAttachBigInt(); + AttachDecision tryAttachStringInt32(); + AttachDecision tryAttachStringNumber(); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + UnaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, + ICState state, JSOp op, HandleValue val, + HandleValue res); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII ToPropertyKeyIRGenerator : public IRGenerator { + HandleValue val_; + + AttachDecision tryAttachInt32(); + AttachDecision tryAttachNumber(); + AttachDecision tryAttachString(); + AttachDecision tryAttachSymbol(); + + void trackAttached(const char* name /* must be a C string literal */); + + public: + ToPropertyKeyIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, + ICState state, HandleValue val); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII BinaryArithIRGenerator : public IRGenerator { + JSOp op_; + HandleValue lhs_; + HandleValue rhs_; + HandleValue res_; + + void trackAttached(const char* name /* must be a C string literal */); + + AttachDecision tryAttachInt32(); + AttachDecision tryAttachDouble(); + AttachDecision tryAttachBitwise(); + AttachDecision tryAttachStringConcat(); + AttachDecision tryAttachStringObjectConcat(); + AttachDecision tryAttachBigInt(); + AttachDecision tryAttachStringInt32Arith(); + + public: + BinaryArithIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, + ICState state, JSOp op, HandleValue lhs, + HandleValue rhs, HandleValue res); + + AttachDecision tryAttachStub(); +}; + +class MOZ_RAII NewArrayIRGenerator : public IRGenerator { +#ifdef JS_CACHEIR_SPEW + JSOp op_; +#endif + HandleObject templateObject_; + BaselineFrame* frame_; + + void trackAttached(const char* name /* must be a C string literal */); + + public: + NewArrayIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, + ICState state, JSOp op, HandleObject templateObj, + BaselineFrame* frame); + + AttachDecision tryAttachStub(); + AttachDecision tryAttachArrayObject(); +}; + +class MOZ_RAII NewObjectIRGenerator : public IRGenerator { +#ifdef JS_CACHEIR_SPEW + JSOp op_; +#endif + HandleObject templateObject_; + BaselineFrame* frame_; + + void trackAttached(const char* name /* must be a C string literal */); + + public: + NewObjectIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, + ICState state, JSOp op, HandleObject templateObj, + BaselineFrame* frame); + + AttachDecision tryAttachStub(); + AttachDecision tryAttachPlainObject(); +}; + +inline bool BytecodeOpCanHaveAllocSite(JSOp op) { + return op == JSOp::NewArray || op == JSOp::NewObject || op == JSOp::NewInit; +} + +class MOZ_RAII CloseIterIRGenerator : public IRGenerator { + HandleObject iter_; + CompletionKind kind_; + + void trackAttached(const char* name /* must be a C string literal */); + + public: + CloseIterIRGenerator(JSContext* cx, HandleScript, jsbytecode* pc, + ICState state, HandleObject iter, CompletionKind kind); + + AttachDecision tryAttachStub(); + AttachDecision tryAttachNoReturnMethod(); + AttachDecision tryAttachScriptedReturn(); +}; + +// Retrieve Xray JIT info set by the embedder. +extern JS::XrayJitInfo* GetXrayJitInfo(); + +} // namespace jit +} // namespace js + +#endif /* jit_CacheIRGenerator_h */ |