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) const34 INLINABLE_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)107 bool 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