/* -*- 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/. */ #include "jit/InlinableNatives.h" #ifdef JS_HAS_INTL_API # include "builtin/intl/Collator.h" # include "builtin/intl/DateTimeFormat.h" # include "builtin/intl/DisplayNames.h" # include "builtin/intl/ListFormat.h" # include "builtin/intl/NumberFormat.h" # include "builtin/intl/PluralRules.h" # include "builtin/intl/RelativeTimeFormat.h" #endif #include "builtin/MapObject.h" #include "js/experimental/JitInfo.h" #include "vm/ArrayBufferObject.h" #include "vm/AsyncIteration.h" #include "vm/Iteration.h" #include "vm/SharedArrayObject.h" using namespace js; using namespace js::jit; #define ADD_NATIVE(native) \ const JSJitInfo js::jit::JitInfo_##native{ \ {nullptr}, \ {uint16_t(InlinableNative::native)}, \ {0}, \ JSJitInfo::InlinableNative}; INLINABLE_NATIVE_LIST(ADD_NATIVE) #undef ADD_NATIVE const JSClass* js::jit::InlinableNativeGuardToClass(InlinableNative native) { switch (native) { #ifdef JS_HAS_INTL_API // Intl natives. case InlinableNative::IntlGuardToCollator: return &CollatorObject::class_; case InlinableNative::IntlGuardToDateTimeFormat: return &DateTimeFormatObject::class_; case InlinableNative::IntlGuardToDisplayNames: return &DisplayNamesObject::class_; case InlinableNative::IntlGuardToListFormat: return &ListFormatObject::class_; case InlinableNative::IntlGuardToNumberFormat: return &NumberFormatObject::class_; case InlinableNative::IntlGuardToPluralRules: return &PluralRulesObject::class_; case InlinableNative::IntlGuardToRelativeTimeFormat: return &RelativeTimeFormatObject::class_; #else case InlinableNative::IntlGuardToCollator: case InlinableNative::IntlGuardToDateTimeFormat: case InlinableNative::IntlGuardToDisplayNames: case InlinableNative::IntlGuardToListFormat: case InlinableNative::IntlGuardToNumberFormat: case InlinableNative::IntlGuardToPluralRules: case InlinableNative::IntlGuardToRelativeTimeFormat: MOZ_CRASH("Intl API disabled"); #endif // Utility intrinsics. case InlinableNative::IntrinsicGuardToArrayIterator: return &ArrayIteratorObject::class_; case InlinableNative::IntrinsicGuardToMapIterator: return &MapIteratorObject::class_; case InlinableNative::IntrinsicGuardToSetIterator: return &SetIteratorObject::class_; case InlinableNative::IntrinsicGuardToStringIterator: return &StringIteratorObject::class_; case InlinableNative::IntrinsicGuardToRegExpStringIterator: return &RegExpStringIteratorObject::class_; case InlinableNative::IntrinsicGuardToWrapForValidIterator: return &WrapForValidIteratorObject::class_; case InlinableNative::IntrinsicGuardToIteratorHelper: return &IteratorHelperObject::class_; case InlinableNative::IntrinsicGuardToAsyncIteratorHelper: return &AsyncIteratorHelperObject::class_; case InlinableNative::IntrinsicGuardToMapObject: return &MapObject::class_; case InlinableNative::IntrinsicGuardToSetObject: return &SetObject::class_; case InlinableNative::IntrinsicGuardToArrayBuffer: return &ArrayBufferObject::class_; case InlinableNative::IntrinsicGuardToSharedArrayBuffer: return &SharedArrayBufferObject::class_; default: MOZ_CRASH("Not a GuardTo instruction"); } } // Returns true if |native| can be inlined cross-realm. Especially inlined // natives that can allocate objects or throw exceptions shouldn't be inlined // cross-realm without a careful analysis because we might use the wrong realm! // // Note that self-hosting intrinsics are never called cross-realm. See the // MOZ_CRASH below. // // If you are adding a new inlinable native, the safe thing is to |return false| // here. bool js::jit::CanInlineNativeCrossRealm(InlinableNative native) { switch (native) { case InlinableNative::MathAbs: case InlinableNative::MathFloor: case InlinableNative::MathCeil: case InlinableNative::MathRound: case InlinableNative::MathClz32: case InlinableNative::MathSqrt: case InlinableNative::MathATan2: case InlinableNative::MathHypot: case InlinableNative::MathMax: case InlinableNative::MathMin: case InlinableNative::MathPow: case InlinableNative::MathImul: case InlinableNative::MathFRound: case InlinableNative::MathTrunc: case InlinableNative::MathSign: case InlinableNative::MathSin: case InlinableNative::MathTan: case InlinableNative::MathCos: case InlinableNative::MathExp: case InlinableNative::MathLog: case InlinableNative::MathASin: case InlinableNative::MathATan: case InlinableNative::MathACos: case InlinableNative::MathLog10: case InlinableNative::MathLog2: case InlinableNative::MathLog1P: case InlinableNative::MathExpM1: case InlinableNative::MathCosH: case InlinableNative::MathSinH: case InlinableNative::MathTanH: case InlinableNative::MathACosH: case InlinableNative::MathASinH: case InlinableNative::MathATanH: case InlinableNative::MathCbrt: case InlinableNative::Boolean: return true; case InlinableNative::Array: // Cross-realm case handled by inlineArray. return true; case InlinableNative::MathRandom: // RNG state is per-realm. return false; case InlinableNative::IntlGuardToCollator: case InlinableNative::IntlGuardToDateTimeFormat: case InlinableNative::IntlGuardToDisplayNames: case InlinableNative::IntlGuardToListFormat: case InlinableNative::IntlGuardToNumberFormat: case InlinableNative::IntlGuardToPluralRules: case InlinableNative::IntlGuardToRelativeTimeFormat: case InlinableNative::IsRegExpObject: case InlinableNative::IsPossiblyWrappedRegExpObject: case InlinableNative::RegExpMatcher: case InlinableNative::RegExpSearcher: case InlinableNative::RegExpPrototypeOptimizable: case InlinableNative::RegExpInstanceOptimizable: case InlinableNative::GetFirstDollarIndex: case InlinableNative::IntrinsicNewArrayIterator: case InlinableNative::IntrinsicNewStringIterator: case InlinableNative::IntrinsicNewRegExpStringIterator: case InlinableNative::IntrinsicStringReplaceString: case InlinableNative::IntrinsicStringSplitString: case InlinableNative::IntrinsicUnsafeSetReservedSlot: case InlinableNative::IntrinsicUnsafeGetReservedSlot: case InlinableNative::IntrinsicUnsafeGetObjectFromReservedSlot: case InlinableNative::IntrinsicUnsafeGetInt32FromReservedSlot: case InlinableNative::IntrinsicUnsafeGetStringFromReservedSlot: case InlinableNative::IntrinsicIsCallable: case InlinableNative::IntrinsicIsConstructor: case InlinableNative::IntrinsicToObject: case InlinableNative::IntrinsicIsObject: case InlinableNative::IntrinsicIsCrossRealmArrayConstructor: case InlinableNative::IntrinsicToInteger: case InlinableNative::IntrinsicToLength: case InlinableNative::IntrinsicIsConstructing: case InlinableNative::IntrinsicIsSuspendedGenerator: case InlinableNative::IntrinsicSubstringKernel: case InlinableNative::IntrinsicGuardToArrayIterator: case InlinableNative::IntrinsicGuardToMapIterator: case InlinableNative::IntrinsicGuardToSetIterator: case InlinableNative::IntrinsicGuardToStringIterator: case InlinableNative::IntrinsicGuardToRegExpStringIterator: case InlinableNative::IntrinsicGuardToWrapForValidIterator: case InlinableNative::IntrinsicGuardToIteratorHelper: case InlinableNative::IntrinsicGuardToAsyncIteratorHelper: case InlinableNative::IntrinsicObjectHasPrototype: case InlinableNative::IntrinsicIsPackedArray: case InlinableNative::IntrinsicGuardToMapObject: case InlinableNative::IntrinsicGetNextMapEntryForIterator: case InlinableNative::IntrinsicGuardToSetObject: case InlinableNative::IntrinsicGetNextSetEntryForIterator: case InlinableNative::IntrinsicGuardToArrayBuffer: case InlinableNative::IntrinsicArrayBufferByteLength: case InlinableNative::IntrinsicPossiblyWrappedArrayBufferByteLength: case InlinableNative::IntrinsicGuardToSharedArrayBuffer: case InlinableNative::IntrinsicIsTypedArrayConstructor: case InlinableNative::IntrinsicIsTypedArray: case InlinableNative::IntrinsicIsPossiblyWrappedTypedArray: case InlinableNative::IntrinsicPossiblyWrappedTypedArrayLength: case InlinableNative::IntrinsicRegExpBuiltinExec: case InlinableNative::IntrinsicRegExpBuiltinExecForTest: case InlinableNative::IntrinsicRegExpExec: case InlinableNative::IntrinsicRegExpExecForTest: case InlinableNative::IntrinsicTypedArrayLength: case InlinableNative::IntrinsicTypedArrayByteOffset: case InlinableNative::IntrinsicTypedArrayElementSize: case InlinableNative::IntrinsicArrayIteratorPrototypeOptimizable: MOZ_CRASH("Unexpected cross-realm intrinsic call"); case InlinableNative::TestBailout: case InlinableNative::TestAssertFloat32: case InlinableNative::TestAssertRecoveredOnBailout: // Testing functions, not worth inlining cross-realm. return false; case InlinableNative::ArrayIsArray: case InlinableNative::ArrayJoin: case InlinableNative::ArrayPop: case InlinableNative::ArrayShift: case InlinableNative::ArrayPush: case InlinableNative::ArraySlice: case InlinableNative::AtomicsCompareExchange: case InlinableNative::AtomicsExchange: case InlinableNative::AtomicsLoad: case InlinableNative::AtomicsStore: case InlinableNative::AtomicsAdd: case InlinableNative::AtomicsSub: case InlinableNative::AtomicsAnd: case InlinableNative::AtomicsOr: case InlinableNative::AtomicsXor: case InlinableNative::AtomicsIsLockFree: case InlinableNative::BigIntAsIntN: case InlinableNative::BigIntAsUintN: case InlinableNative::DataViewGetInt8: case InlinableNative::DataViewGetUint8: case InlinableNative::DataViewGetInt16: case InlinableNative::DataViewGetUint16: case InlinableNative::DataViewGetInt32: case InlinableNative::DataViewGetUint32: case InlinableNative::DataViewGetFloat32: case InlinableNative::DataViewGetFloat64: case InlinableNative::DataViewGetBigInt64: case InlinableNative::DataViewGetBigUint64: case InlinableNative::DataViewSetInt8: case InlinableNative::DataViewSetUint8: case InlinableNative::DataViewSetInt16: case InlinableNative::DataViewSetUint16: case InlinableNative::DataViewSetInt32: case InlinableNative::DataViewSetUint32: case InlinableNative::DataViewSetFloat32: case InlinableNative::DataViewSetFloat64: case InlinableNative::DataViewSetBigInt64: case InlinableNative::DataViewSetBigUint64: case InlinableNative::FunctionBind: case InlinableNative::MapGet: case InlinableNative::MapHas: case InlinableNative::Number: case InlinableNative::NumberParseInt: case InlinableNative::NumberToString: case InlinableNative::ReflectGetPrototypeOf: case InlinableNative::SetHas: case InlinableNative::String: case InlinableNative::StringToString: case InlinableNative::StringValueOf: case InlinableNative::StringCharCodeAt: case InlinableNative::StringFromCharCode: case InlinableNative::StringFromCodePoint: case InlinableNative::StringCharAt: case InlinableNative::StringIndexOf: case InlinableNative::StringStartsWith: case InlinableNative::StringEndsWith: case InlinableNative::StringToLowerCase: case InlinableNative::StringToUpperCase: case InlinableNative::Object: case InlinableNative::ObjectCreate: case InlinableNative::ObjectIs: case InlinableNative::ObjectIsPrototypeOf: case InlinableNative::ObjectToString: case InlinableNative::TypedArrayConstructor: #ifdef FUZZING_JS_FUZZILLI case InlinableNative::FuzzilliHash: #endif // Default to false for most natives. return false; case InlinableNative::Limit: break; } MOZ_CRASH("Unknown native"); }