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 #include "jit/InlinableNatives.h" 8 9 #ifdef JS_HAS_INTL_API 10 # include "builtin/intl/Collator.h" 11 # include "builtin/intl/DateTimeFormat.h" 12 # include "builtin/intl/DisplayNames.h" 13 # include "builtin/intl/ListFormat.h" 14 # include "builtin/intl/NumberFormat.h" 15 # include "builtin/intl/PluralRules.h" 16 # include "builtin/intl/RelativeTimeFormat.h" 17 #endif 18 #include "builtin/MapObject.h" 19 #include "js/experimental/JitInfo.h" 20 #include "vm/ArrayBufferObject.h" 21 #include "vm/AsyncIteration.h" 22 #include "vm/Iteration.h" 23 #include "vm/SharedArrayObject.h" 24 25 using namespace js; 26 using namespace js::jit; 27 28 #define ADD_NATIVE(native) \ 29 const JSJitInfo js::jit::JitInfo_##native{ \ 30 {nullptr}, \ 31 {uint16_t(InlinableNative::native)}, \ 32 {0}, \ 33 JSJitInfo::InlinableNative}; INLINABLE_NATIVE_LIST(ADD_NATIVE) const34INLINABLE_NATIVE_LIST(ADD_NATIVE) 35 #undef ADD_NATIVE 36 37 const JSClass* js::jit::InlinableNativeGuardToClass(InlinableNative native) { 38 switch (native) { 39 #ifdef JS_HAS_INTL_API 40 // Intl natives. 41 case InlinableNative::IntlGuardToCollator: 42 return &CollatorObject::class_; 43 case InlinableNative::IntlGuardToDateTimeFormat: 44 return &DateTimeFormatObject::class_; 45 case InlinableNative::IntlGuardToDisplayNames: 46 return &DisplayNamesObject::class_; 47 case InlinableNative::IntlGuardToListFormat: 48 return &ListFormatObject::class_; 49 case InlinableNative::IntlGuardToNumberFormat: 50 return &NumberFormatObject::class_; 51 case InlinableNative::IntlGuardToPluralRules: 52 return &PluralRulesObject::class_; 53 case InlinableNative::IntlGuardToRelativeTimeFormat: 54 return &RelativeTimeFormatObject::class_; 55 #else 56 case InlinableNative::IntlGuardToCollator: 57 case InlinableNative::IntlGuardToDateTimeFormat: 58 case InlinableNative::IntlGuardToDisplayNames: 59 case InlinableNative::IntlGuardToListFormat: 60 case InlinableNative::IntlGuardToNumberFormat: 61 case InlinableNative::IntlGuardToPluralRules: 62 case InlinableNative::IntlGuardToRelativeTimeFormat: 63 MOZ_CRASH("Intl API disabled"); 64 #endif 65 66 // Utility intrinsics. 67 case InlinableNative::IntrinsicGuardToArrayIterator: 68 return &ArrayIteratorObject::class_; 69 case InlinableNative::IntrinsicGuardToMapIterator: 70 return &MapIteratorObject::class_; 71 case InlinableNative::IntrinsicGuardToSetIterator: 72 return &SetIteratorObject::class_; 73 case InlinableNative::IntrinsicGuardToStringIterator: 74 return &StringIteratorObject::class_; 75 case InlinableNative::IntrinsicGuardToRegExpStringIterator: 76 return &RegExpStringIteratorObject::class_; 77 case InlinableNative::IntrinsicGuardToWrapForValidIterator: 78 return &WrapForValidIteratorObject::class_; 79 case InlinableNative::IntrinsicGuardToIteratorHelper: 80 return &IteratorHelperObject::class_; 81 case InlinableNative::IntrinsicGuardToAsyncIteratorHelper: 82 return &AsyncIteratorHelperObject::class_; 83 84 case InlinableNative::IntrinsicGuardToMapObject: 85 return &MapObject::class_; 86 case InlinableNative::IntrinsicGuardToSetObject: 87 return &SetObject::class_; 88 case InlinableNative::IntrinsicGuardToArrayBuffer: 89 return &ArrayBufferObject::class_; 90 case InlinableNative::IntrinsicGuardToSharedArrayBuffer: 91 return &SharedArrayBufferObject::class_; 92 93 default: 94 MOZ_CRASH("Not a GuardTo instruction"); 95 } 96 } 97 98 // Returns true if |native| can be inlined cross-realm. Especially inlined 99 // natives that can allocate objects or throw exceptions shouldn't be inlined 100 // cross-realm without a careful analysis because we might use the wrong realm! 101 // 102 // Note that self-hosting intrinsics are never called cross-realm. See the 103 // MOZ_CRASH below. 104 // 105 // If you are adding a new inlinable native, the safe thing is to |return false| 106 // here. CanInlineNativeCrossRealm(InlinableNative native)107bool js::jit::CanInlineNativeCrossRealm(InlinableNative native) { 108 switch (native) { 109 case InlinableNative::MathAbs: 110 case InlinableNative::MathFloor: 111 case InlinableNative::MathCeil: 112 case InlinableNative::MathRound: 113 case InlinableNative::MathClz32: 114 case InlinableNative::MathSqrt: 115 case InlinableNative::MathATan2: 116 case InlinableNative::MathHypot: 117 case InlinableNative::MathMax: 118 case InlinableNative::MathMin: 119 case InlinableNative::MathPow: 120 case InlinableNative::MathImul: 121 case InlinableNative::MathFRound: 122 case InlinableNative::MathTrunc: 123 case InlinableNative::MathSign: 124 case InlinableNative::MathSin: 125 case InlinableNative::MathTan: 126 case InlinableNative::MathCos: 127 case InlinableNative::MathExp: 128 case InlinableNative::MathLog: 129 case InlinableNative::MathASin: 130 case InlinableNative::MathATan: 131 case InlinableNative::MathACos: 132 case InlinableNative::MathLog10: 133 case InlinableNative::MathLog2: 134 case InlinableNative::MathLog1P: 135 case InlinableNative::MathExpM1: 136 case InlinableNative::MathCosH: 137 case InlinableNative::MathSinH: 138 case InlinableNative::MathTanH: 139 case InlinableNative::MathACosH: 140 case InlinableNative::MathASinH: 141 case InlinableNative::MathATanH: 142 case InlinableNative::MathCbrt: 143 case InlinableNative::Boolean: 144 return true; 145 146 case InlinableNative::Array: 147 // Cross-realm case handled by inlineArray. 148 return true; 149 150 case InlinableNative::MathRandom: 151 // RNG state is per-realm. 152 return false; 153 154 case InlinableNative::IntlGuardToCollator: 155 case InlinableNative::IntlGuardToDateTimeFormat: 156 case InlinableNative::IntlGuardToDisplayNames: 157 case InlinableNative::IntlGuardToListFormat: 158 case InlinableNative::IntlGuardToNumberFormat: 159 case InlinableNative::IntlGuardToPluralRules: 160 case InlinableNative::IntlGuardToRelativeTimeFormat: 161 case InlinableNative::IsRegExpObject: 162 case InlinableNative::IsPossiblyWrappedRegExpObject: 163 case InlinableNative::RegExpMatcher: 164 case InlinableNative::RegExpSearcher: 165 case InlinableNative::RegExpTester: 166 case InlinableNative::RegExpPrototypeOptimizable: 167 case InlinableNative::RegExpInstanceOptimizable: 168 case InlinableNative::GetFirstDollarIndex: 169 case InlinableNative::IntrinsicNewArrayIterator: 170 case InlinableNative::IntrinsicNewStringIterator: 171 case InlinableNative::IntrinsicNewRegExpStringIterator: 172 case InlinableNative::IntrinsicStringReplaceString: 173 case InlinableNative::IntrinsicStringSplitString: 174 case InlinableNative::IntrinsicUnsafeSetReservedSlot: 175 case InlinableNative::IntrinsicUnsafeGetReservedSlot: 176 case InlinableNative::IntrinsicUnsafeGetObjectFromReservedSlot: 177 case InlinableNative::IntrinsicUnsafeGetInt32FromReservedSlot: 178 case InlinableNative::IntrinsicUnsafeGetStringFromReservedSlot: 179 case InlinableNative::IntrinsicUnsafeGetBooleanFromReservedSlot: 180 case InlinableNative::IntrinsicIsCallable: 181 case InlinableNative::IntrinsicIsConstructor: 182 case InlinableNative::IntrinsicToObject: 183 case InlinableNative::IntrinsicIsObject: 184 case InlinableNative::IntrinsicIsCrossRealmArrayConstructor: 185 case InlinableNative::IntrinsicToInteger: 186 case InlinableNative::IntrinsicToLength: 187 case InlinableNative::IntrinsicIsConstructing: 188 case InlinableNative::IntrinsicIsSuspendedGenerator: 189 case InlinableNative::IntrinsicSubstringKernel: 190 case InlinableNative::IntrinsicGuardToArrayIterator: 191 case InlinableNative::IntrinsicGuardToMapIterator: 192 case InlinableNative::IntrinsicGuardToSetIterator: 193 case InlinableNative::IntrinsicGuardToStringIterator: 194 case InlinableNative::IntrinsicGuardToRegExpStringIterator: 195 case InlinableNative::IntrinsicGuardToWrapForValidIterator: 196 case InlinableNative::IntrinsicGuardToIteratorHelper: 197 case InlinableNative::IntrinsicGuardToAsyncIteratorHelper: 198 case InlinableNative::IntrinsicObjectHasPrototype: 199 case InlinableNative::IntrinsicFinishBoundFunctionInit: 200 case InlinableNative::IntrinsicIsPackedArray: 201 case InlinableNative::IntrinsicGuardToMapObject: 202 case InlinableNative::IntrinsicGetNextMapEntryForIterator: 203 case InlinableNative::IntrinsicGuardToSetObject: 204 case InlinableNative::IntrinsicGetNextSetEntryForIterator: 205 case InlinableNative::IntrinsicGuardToArrayBuffer: 206 case InlinableNative::IntrinsicArrayBufferByteLength: 207 case InlinableNative::IntrinsicPossiblyWrappedArrayBufferByteLength: 208 case InlinableNative::IntrinsicGuardToSharedArrayBuffer: 209 case InlinableNative::IntrinsicIsTypedArrayConstructor: 210 case InlinableNative::IntrinsicIsTypedArray: 211 case InlinableNative::IntrinsicIsPossiblyWrappedTypedArray: 212 case InlinableNative::IntrinsicPossiblyWrappedTypedArrayLength: 213 case InlinableNative::IntrinsicTypedArrayLength: 214 case InlinableNative::IntrinsicTypedArrayByteOffset: 215 case InlinableNative::IntrinsicTypedArrayElementSize: 216 case InlinableNative::IntrinsicArrayIteratorPrototypeOptimizable: 217 MOZ_CRASH("Unexpected cross-realm intrinsic call"); 218 219 case InlinableNative::TestBailout: 220 case InlinableNative::TestAssertFloat32: 221 case InlinableNative::TestAssertRecoveredOnBailout: 222 // Testing functions, not worth inlining cross-realm. 223 return false; 224 225 case InlinableNative::ArrayIsArray: 226 case InlinableNative::ArrayJoin: 227 case InlinableNative::ArrayPop: 228 case InlinableNative::ArrayShift: 229 case InlinableNative::ArrayPush: 230 case InlinableNative::ArraySlice: 231 case InlinableNative::AtomicsCompareExchange: 232 case InlinableNative::AtomicsExchange: 233 case InlinableNative::AtomicsLoad: 234 case InlinableNative::AtomicsStore: 235 case InlinableNative::AtomicsAdd: 236 case InlinableNative::AtomicsSub: 237 case InlinableNative::AtomicsAnd: 238 case InlinableNative::AtomicsOr: 239 case InlinableNative::AtomicsXor: 240 case InlinableNative::AtomicsIsLockFree: 241 case InlinableNative::BigIntAsIntN: 242 case InlinableNative::BigIntAsUintN: 243 case InlinableNative::DataViewGetInt8: 244 case InlinableNative::DataViewGetUint8: 245 case InlinableNative::DataViewGetInt16: 246 case InlinableNative::DataViewGetUint16: 247 case InlinableNative::DataViewGetInt32: 248 case InlinableNative::DataViewGetUint32: 249 case InlinableNative::DataViewGetFloat32: 250 case InlinableNative::DataViewGetFloat64: 251 case InlinableNative::DataViewGetBigInt64: 252 case InlinableNative::DataViewGetBigUint64: 253 case InlinableNative::DataViewSetInt8: 254 case InlinableNative::DataViewSetUint8: 255 case InlinableNative::DataViewSetInt16: 256 case InlinableNative::DataViewSetUint16: 257 case InlinableNative::DataViewSetInt32: 258 case InlinableNative::DataViewSetUint32: 259 case InlinableNative::DataViewSetFloat32: 260 case InlinableNative::DataViewSetFloat64: 261 case InlinableNative::DataViewSetBigInt64: 262 case InlinableNative::DataViewSetBigUint64: 263 case InlinableNative::MapGet: 264 case InlinableNative::MapHas: 265 case InlinableNative::NumberToString: 266 case InlinableNative::ReflectGetPrototypeOf: 267 case InlinableNative::SetHas: 268 case InlinableNative::String: 269 case InlinableNative::StringToString: 270 case InlinableNative::StringValueOf: 271 case InlinableNative::StringCharCodeAt: 272 case InlinableNative::StringFromCharCode: 273 case InlinableNative::StringFromCodePoint: 274 case InlinableNative::StringCharAt: 275 case InlinableNative::StringToLowerCase: 276 case InlinableNative::StringToUpperCase: 277 case InlinableNative::Object: 278 case InlinableNative::ObjectCreate: 279 case InlinableNative::ObjectIs: 280 case InlinableNative::ObjectIsPrototypeOf: 281 case InlinableNative::ObjectToString: 282 case InlinableNative::TypedArrayConstructor: 283 // Default to false for most natives. 284 return false; 285 286 case InlinableNative::Limit: 287 break; 288 } 289 MOZ_CRASH("Unknown native"); 290 } 291