[SM91] Update to Spidermonkey 91.1.3 APIs
[0ad.git] / libraries / source / spidermonkey / include-win32-release / js / experimental / JitInfo.h
blob1b070021bd12d07c9ef18fa593e2a1b0762ddec2
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/. */
7 #ifndef js_experimental_JitInfo_h
8 #define js_experimental_JitInfo_h
10 #include "mozilla/Assertions.h" // MOZ_ASSERT
12 #include <stddef.h> // size_t
13 #include <stdint.h> // uint16_t, uint32_t
15 #include "js/CallArgs.h" // JS::CallArgs, JS::detail::CallArgsBase, JSNative
16 #include "js/RootingAPI.h" // JS::{,Mutable}Handle, JS::Rooted
17 #include "js/Value.h" // JS::Value, JSValueType
19 namespace js {
21 namespace jit {
23 enum class InlinableNative : uint16_t;
25 } // namespace jit
27 } // namespace js
29 /**
30 * A class, expected to be passed by value, which represents the CallArgs for a
31 * JSJitGetterOp.
33 class JSJitGetterCallArgs : protected JS::MutableHandle<JS::Value> {
34 public:
35 explicit JSJitGetterCallArgs(const JS::CallArgs& args)
36 : JS::MutableHandle<JS::Value>(args.rval()) {}
38 explicit JSJitGetterCallArgs(JS::Rooted<JS::Value>* rooted)
39 : JS::MutableHandle<JS::Value>(rooted) {}
41 explicit JSJitGetterCallArgs(JS::MutableHandle<JS::Value> handle)
42 : JS::MutableHandle<JS::Value>(handle) {}
44 JS::MutableHandle<JS::Value> rval() { return *this; }
47 /**
48 * A class, expected to be passed by value, which represents the CallArgs for a
49 * JSJitSetterOp.
51 class JSJitSetterCallArgs : protected JS::MutableHandle<JS::Value> {
52 public:
53 explicit JSJitSetterCallArgs(const JS::CallArgs& args)
54 : JS::MutableHandle<JS::Value>(args[0]) {}
56 explicit JSJitSetterCallArgs(JS::Rooted<JS::Value>* rooted)
57 : JS::MutableHandle<JS::Value>(rooted) {}
59 JS::MutableHandle<JS::Value> operator[](unsigned i) {
60 MOZ_ASSERT(i == 0);
61 return *this;
64 unsigned length() const { return 1; }
66 // Add get() or maybe hasDefined() as needed
69 struct JSJitMethodCallArgsTraits;
71 /**
72 * A class, expected to be passed by reference, which represents the CallArgs
73 * for a JSJitMethodOp.
75 class JSJitMethodCallArgs
76 : protected JS::detail::CallArgsBase<JS::detail::NoUsedRval> {
77 private:
78 using Base = JS::detail::CallArgsBase<JS::detail::NoUsedRval>;
79 friend struct JSJitMethodCallArgsTraits;
81 public:
82 explicit JSJitMethodCallArgs(const JS::CallArgs& args) {
83 argv_ = args.array();
84 argc_ = args.length();
87 JS::MutableHandle<JS::Value> rval() const { return Base::rval(); }
89 unsigned length() const { return Base::length(); }
91 JS::MutableHandle<JS::Value> operator[](unsigned i) const {
92 return Base::operator[](i);
95 bool hasDefined(unsigned i) const { return Base::hasDefined(i); }
97 JSObject& callee() const {
98 // We can't use Base::callee() because that will try to poke at
99 // this->usedRval_, which we don't have.
100 return argv_[-2].toObject();
103 JS::Handle<JS::Value> get(unsigned i) const { return Base::get(i); }
105 bool requireAtLeast(JSContext* cx, const char* fnname,
106 unsigned required) const {
107 // Can just forward to Base, since it only needs the length and we
108 // forward that already.
109 return Base::requireAtLeast(cx, fnname, required);
113 struct JSJitMethodCallArgsTraits {
114 static constexpr size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_);
115 static constexpr size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_);
118 using JSJitGetterOp = bool (*)(JSContext*, JS::Handle<JSObject*>, void*,
119 JSJitGetterCallArgs);
120 using JSJitSetterOp = bool (*)(JSContext*, JS::Handle<JSObject*>, void*,
121 JSJitSetterCallArgs);
122 using JSJitMethodOp = bool (*)(JSContext*, JS::Handle<JSObject*>, void*,
123 const JSJitMethodCallArgs&);
126 * This struct contains metadata passed from the DOM to the JS Engine for JIT
127 * optimizations on DOM property accessors.
129 * Eventually, this should be made available to general JSAPI users as *not*
130 * experimental and *not* a friend API, but we're not ready to do so yet.
132 class JSJitInfo {
133 public:
134 enum OpType {
135 Getter,
136 Setter,
137 Method,
138 StaticMethod,
139 InlinableNative,
140 IgnoresReturnValueNative,
141 // Must be last
142 OpTypeCount
145 enum ArgType {
146 // Basic types
147 String = (1 << 0),
148 Integer = (1 << 1), // Only 32-bit or less
149 Double = (1 << 2), // Maybe we want to add Float sometime too
150 Boolean = (1 << 3),
151 Object = (1 << 4),
152 Null = (1 << 5),
154 // And derived types
155 Numeric = Integer | Double,
156 // Should "Primitive" use the WebIDL definition, which
157 // excludes string and null, or the typical JS one that includes them?
158 Primitive = Numeric | Boolean | Null | String,
159 ObjectOrNull = Object | Null,
160 Any = ObjectOrNull | Primitive,
162 // Our sentinel value.
163 ArgTypeListEnd = (1 << 31)
166 static_assert(Any & String, "Any must include String");
167 static_assert(Any & Integer, "Any must include Integer");
168 static_assert(Any & Double, "Any must include Double");
169 static_assert(Any & Boolean, "Any must include Boolean");
170 static_assert(Any & Object, "Any must include Object");
171 static_assert(Any & Null, "Any must include Null");
174 * An enum that describes what this getter/setter/method aliases. This
175 * determines what things can be hoisted past this call, and if this
176 * call is movable what it can be hoisted past.
178 enum AliasSet {
180 * Alias nothing: a constant value, getting it can't affect any other
181 * values, nothing can affect it.
183 AliasNone,
186 * Alias things that can modify the DOM but nothing else. Doing the
187 * call can't affect the behavior of any other function.
189 AliasDOMSets,
192 * Alias the world. Calling this can change arbitrary values anywhere
193 * in the system. Most things fall in this bucket.
195 AliasEverything,
197 /** Must be last. */
198 AliasSetCount
201 bool needsOuterizedThisObject() const {
202 return type() != Getter && type() != Setter;
205 bool isTypedMethodJitInfo() const { return isTypedMethod; }
207 OpType type() const { return OpType(type_); }
209 AliasSet aliasSet() const { return AliasSet(aliasSet_); }
211 JSValueType returnType() const { return JSValueType(returnType_); }
213 union {
214 JSJitGetterOp getter;
215 JSJitSetterOp setter;
216 JSJitMethodOp method;
217 /** A DOM static method, used for Promise wrappers */
218 JSNative staticMethod;
219 JSNative ignoresReturnValueMethod;
222 static unsigned offsetOfIgnoresReturnValueNative() {
223 return offsetof(JSJitInfo, ignoresReturnValueMethod);
226 union {
227 uint16_t protoID;
228 js::jit::InlinableNative inlinableNative;
231 union {
232 uint16_t depth;
234 // Additional opcode for some InlinableNative functions.
235 uint16_t nativeOp;
238 // These fields are carefully packed to take up 4 bytes. If you need more
239 // bits for whatever reason, please see if you can steal bits from existing
240 // fields before adding more members to this structure.
241 static constexpr size_t OpTypeBits = 4;
242 static constexpr size_t AliasSetBits = 4;
243 static constexpr size_t ReturnTypeBits = 8;
244 static constexpr size_t SlotIndexBits = 10;
246 /** The OpType that says what sort of function we are. */
247 uint32_t type_ : OpTypeBits;
250 * The alias set for this op. This is a _minimal_ alias set; in
251 * particular for a method it does not include whatever argument
252 * conversions might do. That's covered by argTypes and runtime
253 * analysis of the actual argument types being passed in.
255 uint32_t aliasSet_ : AliasSetBits;
257 /** The return type tag. Might be JSVAL_TYPE_UNKNOWN. */
258 uint32_t returnType_ : ReturnTypeBits;
260 static_assert(OpTypeCount <= (1 << OpTypeBits),
261 "Not enough space for OpType");
262 static_assert(AliasSetCount <= (1 << AliasSetBits),
263 "Not enough space for AliasSet");
264 static_assert((sizeof(JSValueType) * 8) <= ReturnTypeBits,
265 "Not enough space for JSValueType");
267 /** Is op fallible? False in setters. */
268 uint32_t isInfallible : 1;
271 * Is op movable? To be movable the op must
272 * not AliasEverything, but even that might
273 * not be enough (e.g. in cases when it can
274 * throw or is explicitly not movable).
276 uint32_t isMovable : 1;
279 * Can op be dead-code eliminated? Again, this
280 * depends on whether the op can throw, in
281 * addition to the alias set.
283 uint32_t isEliminatable : 1;
285 // XXXbz should we have a JSValueType for the type of the member?
287 * True if this is a getter that can always
288 * get the value from a slot of the "this" object.
290 uint32_t isAlwaysInSlot : 1;
293 * True if this is a getter that can sometimes (if the slot doesn't contain
294 * UndefinedValue()) get the value from a slot of the "this" object.
296 uint32_t isLazilyCachedInSlot : 1;
298 /** True if this is an instance of JSTypedMethodJitInfo. */
299 uint32_t isTypedMethod : 1;
302 * If isAlwaysInSlot or isSometimesInSlot is true,
303 * the index of the slot to get the value from.
304 * Otherwise 0.
306 uint32_t slotIndex : SlotIndexBits;
308 static constexpr size_t maxSlotIndex = (1 << SlotIndexBits) - 1;
311 static_assert(sizeof(JSJitInfo) == (sizeof(void*) + 2 * sizeof(uint32_t)),
312 "There are several thousand instances of JSJitInfo stored in "
313 "a binary. Please don't increase its space requirements without "
314 "verifying that there is no other way forward (better packing, "
315 "smaller datatypes for fields, subclassing, etc.).");
317 struct JSTypedMethodJitInfo {
318 // We use C-style inheritance here, rather than C++ style inheritance
319 // because not all compilers support brace-initialization for non-aggregate
320 // classes. Using C++ style inheritance and constructors instead of
321 // brace-initialization would also force the creation of static
322 // constructors (on some compilers) when JSJitInfo and JSTypedMethodJitInfo
323 // structures are declared. Since there can be several thousand of these
324 // structures present and we want to have roughly equivalent performance
325 // across a range of compilers, we do things manually.
326 JSJitInfo base;
328 const JSJitInfo::ArgType* const argTypes; /* For a method, a list of sets of
329 types that the function
330 expects. This can be used,
331 for example, to figure out
332 when argument coercions can
333 have side-effects. */
336 #endif // js_experimental_JitInfo_h