Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
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 jit_TypePolicy_h
8 #define jit_TypePolicy_h
10 #include "jit/IonAllocPolicy.h"
11 #include "jit/IonTypes.h"
13 namespace js {
14 namespace jit {
16 class MInstruction;
17 class MDefinition;
19 // A type policy directs the type analysis phases, which insert conversion,
20 // boxing, unboxing, and type changes as necessary.
21 class TypePolicy
22 {
23 public:
24 // Analyze the inputs of the instruction and perform one of the following
25 // actions for each input:
26 // * Nothing; the input already type-checks.
27 // * If untyped, optionally ask the input to try and specialize its value.
28 // * Replace the operand with a conversion instruction.
29 // * Insert an unconditional deoptimization (no conversion possible).
30 virtual bool adjustInputs(TempAllocator &alloc, MInstruction *def) = 0;
31 };
33 class BoxInputsPolicy : public TypePolicy
34 {
35 protected:
36 static MDefinition *boxAt(TempAllocator &alloc, MInstruction *at, MDefinition *operand);
38 public:
39 static MDefinition *alwaysBoxAt(TempAllocator &alloc, MInstruction *at, MDefinition *operand);
40 virtual bool adjustInputs(TempAllocator &alloc, MInstruction *def);
41 };
43 class ArithPolicy : public BoxInputsPolicy
44 {
45 protected:
46 // Specifies three levels of specialization:
47 // - < Value. This input is expected and required.
48 // - == Any. Inputs are probably primitive.
49 // - == None. This op should not be specialized.
50 MIRType specialization_;
52 public:
53 bool adjustInputs(TempAllocator &alloc, MInstruction *def);
54 };
56 class BitwisePolicy : public BoxInputsPolicy
57 {
58 protected:
59 // Specifies three levels of specialization:
60 // - < Value. This input is expected and required.
61 // - == Any. Inputs are probably primitive.
62 // - == None. This op should not be specialized.
63 MIRType specialization_;
65 public:
66 bool adjustInputs(TempAllocator &alloc, MInstruction *def);
68 MIRType specialization() const {
69 return specialization_;
70 }
71 };
73 class ComparePolicy : public BoxInputsPolicy
74 {
75 bool adjustInputs(TempAllocator &alloc, MInstruction *def);
76 };
78 // Policy for MTest instructions.
79 class TestPolicy : public BoxInputsPolicy
80 {
81 public:
82 bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
83 };
85 class TypeBarrierPolicy : public BoxInputsPolicy
86 {
87 public:
88 bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
89 };
91 class CallPolicy : public BoxInputsPolicy
92 {
93 public:
94 bool adjustInputs(TempAllocator &alloc, MInstruction *def);
95 };
97 // Policy for MPow. First operand Double; second Double or Int32.
98 class PowPolicy : public BoxInputsPolicy
99 {
100 MIRType specialization_;
102 public:
103 PowPolicy(MIRType specialization)
104 : specialization_(specialization)
105 { }
107 bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
108 };
110 // Expect a string for operand Op. If the input is a Value, it is unboxed.
111 template <unsigned Op>
112 class StringPolicy : public BoxInputsPolicy
113 {
114 public:
115 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
116 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
117 return staticAdjustInputs(alloc, def);
118 }
119 };
121 // Expect a string for operand Op. Else a ToString instruction is inserted.
122 template <unsigned Op>
123 class ConvertToStringPolicy : public BoxInputsPolicy
124 {
125 public:
126 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
127 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
128 return staticAdjustInputs(alloc, def);
129 }
130 };
132 // Expect an Int for operand Op. If the input is a Value, it is unboxed.
133 template <unsigned Op>
134 class IntPolicy : public BoxInputsPolicy
135 {
136 public:
137 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
138 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
139 return staticAdjustInputs(alloc, def);
140 }
141 };
143 // Expect an Int for operand Op. Else a ToInt32 instruction is inserted.
144 template <unsigned Op>
145 class ConvertToInt32Policy : public BoxInputsPolicy
146 {
147 public:
148 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
149 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
150 return staticAdjustInputs(alloc, def);
151 }
152 };
154 // Expect a double for operand Op. If the input is a Value, it is unboxed.
155 template <unsigned Op>
156 class DoublePolicy : public BoxInputsPolicy
157 {
158 public:
159 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
160 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
161 return staticAdjustInputs(alloc, def);
162 }
163 };
165 // Expect a float32 for operand Op. If the input is a Value, it is unboxed.
166 template <unsigned Op>
167 class Float32Policy : public BoxInputsPolicy
168 {
169 public:
170 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
171 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
172 return staticAdjustInputs(alloc, def);
173 }
174 };
176 // Expect a float32 OR a double for operand Op, but will prioritize Float32
177 // if the result type is set as such. If the input is a Value, it is unboxed.
178 template <unsigned Op>
179 class FloatingPointPolicy : public TypePolicy
180 {
181 MIRType policyType_;
183 public:
184 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
185 if (policyType_ == MIRType_Double)
186 return DoublePolicy<Op>::staticAdjustInputs(alloc, def);
187 return Float32Policy<Op>::staticAdjustInputs(alloc, def);
188 }
189 void setPolicyType(MIRType type) {
190 policyType_ = type;
191 }
192 };
194 template <unsigned Op>
195 class NoFloatPolicy : public TypePolicy
196 {
197 public:
198 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
199 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
200 return staticAdjustInputs(alloc, def);
201 }
202 };
204 // Box objects or strings as an input to a ToDouble instruction.
205 class ToDoublePolicy : public BoxInputsPolicy
206 {
207 public:
208 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
209 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
210 return staticAdjustInputs(alloc, def);
211 }
212 };
214 // Box objects, strings and undefined as input to a ToInt32 instruction.
215 class ToInt32Policy : public BoxInputsPolicy
216 {
217 public:
218 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
219 bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
220 return staticAdjustInputs(alloc, def);
221 }
222 };
224 template <unsigned Op>
225 class ObjectPolicy : public BoxInputsPolicy
226 {
227 public:
228 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
229 bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
230 return staticAdjustInputs(alloc, ins);
231 }
232 };
234 // Single-object input. If the input is a Value, it is unboxed. If it is
235 // a primitive, we use ValueToNonNullObject.
236 class SingleObjectPolicy : public ObjectPolicy<0>
237 { };
239 template <unsigned Op>
240 class BoxPolicy : public BoxInputsPolicy
241 {
242 public:
243 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
244 bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
245 return staticAdjustInputs(alloc, ins);
246 }
247 };
249 // Boxes everything except inputs of type Type.
250 template <unsigned Op, MIRType Type>
251 class BoxExceptPolicy : public TypePolicy
252 {
253 public:
254 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
255 bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
256 return staticAdjustInputs(alloc, ins);
257 }
258 };
260 // Combine multiple policies.
261 template <class Lhs, class Rhs>
262 class MixPolicy : public TypePolicy
263 {
264 public:
265 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins) {
266 return Lhs::staticAdjustInputs(alloc, ins) && Rhs::staticAdjustInputs(alloc, ins);
267 }
268 virtual bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
269 return staticAdjustInputs(alloc, ins);
270 }
271 };
273 // Combine three policies.
274 template <class Policy1, class Policy2, class Policy3>
275 class Mix3Policy : public TypePolicy
276 {
277 public:
278 static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins) {
279 return Policy1::staticAdjustInputs(alloc, ins) &&
280 Policy2::staticAdjustInputs(alloc, ins) &&
281 Policy3::staticAdjustInputs(alloc, ins);
282 }
283 virtual bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
284 return staticAdjustInputs(alloc, ins);
285 }
286 };
288 class CallSetElementPolicy : public SingleObjectPolicy
289 {
290 public:
291 bool adjustInputs(TempAllocator &alloc, MInstruction *def);
292 };
294 // First operand will be boxed to a Value (except for an object)
295 // Second operand (if specified) will forcefully be unboxed to an object
296 class InstanceOfPolicy : public TypePolicy
297 {
298 public:
299 bool adjustInputs(TempAllocator &alloc, MInstruction *def);
300 };
302 class StoreTypedArrayPolicy : public BoxInputsPolicy
303 {
304 protected:
305 bool adjustValueInput(TempAllocator &alloc, MInstruction *ins, int arrayType, MDefinition *value, int valueOperand);
307 public:
308 bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
309 };
311 class StoreTypedArrayHolePolicy : public StoreTypedArrayPolicy
312 {
313 public:
314 bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
315 };
317 class StoreTypedArrayElementStaticPolicy : public StoreTypedArrayPolicy
318 {
319 public:
320 bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
321 };
323 // Accepts integers and doubles. Everything else is boxed.
324 class ClampPolicy : public BoxInputsPolicy
325 {
326 public:
327 bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
328 };
330 class FilterTypeSetPolicy : public BoxInputsPolicy
331 {
332 public:
333 bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
334 };
336 static inline bool
337 CoercesToDouble(MIRType type)
338 {
339 if (type == MIRType_Undefined || IsFloatingPointType(type))
340 return true;
341 return false;
342 }
345 } // namespace jit
346 } // namespace js
348 #endif /* jit_TypePolicy_h */