Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_
6 : #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_
7 :
8 : #include <iosfwd>
9 :
10 : #include "src/base/compiler-specific.h"
11 : #include "src/compiler/operator.h"
12 : #include "src/compiler/types.h"
13 : #include "src/globals.h"
14 : #include "src/handles.h"
15 : #include "src/machine-type.h"
16 : #include "src/objects.h"
17 : #include "src/zone/zone-handle-set.h"
18 :
19 : namespace v8 {
20 : namespace internal {
21 :
22 : // Forward declarations.
23 : class Zone;
24 :
25 : namespace compiler {
26 :
27 : // Forward declarations.
28 : class Operator;
29 : struct SimplifiedOperatorGlobalCache;
30 :
31 : enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase };
32 :
33 : size_t hash_value(BaseTaggedness);
34 :
35 : std::ostream& operator<<(std::ostream&, BaseTaggedness);
36 :
37 :
38 : // An access descriptor for loads/stores of array buffers.
39 : class BufferAccess final {
40 : public:
41 : explicit BufferAccess(ExternalArrayType external_array_type)
42 12365 : : external_array_type_(external_array_type) {}
43 :
44 20916 : ExternalArrayType external_array_type() const { return external_array_type_; }
45 : MachineType machine_type() const;
46 :
47 : private:
48 : ExternalArrayType const external_array_type_;
49 : };
50 :
51 : V8_EXPORT_PRIVATE bool operator==(BufferAccess, BufferAccess);
52 : bool operator!=(BufferAccess, BufferAccess);
53 :
54 : size_t hash_value(BufferAccess);
55 :
56 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BufferAccess);
57 :
58 : V8_EXPORT_PRIVATE BufferAccess const BufferAccessOf(const Operator* op)
59 : WARN_UNUSED_RESULT;
60 :
61 : // An access descriptor for loads/stores of fixed structures like field
62 : // accesses of heap objects. Accesses from either tagged or untagged base
63 : // pointers are supported; untagging is done automatically during lowering.
64 : struct FieldAccess {
65 : BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged.
66 : int offset; // offset of the field, without tag.
67 : MaybeHandle<Name> name; // debugging only.
68 : MaybeHandle<Map> map; // map of the field value (if known).
69 : Type* type; // type of the field.
70 : MachineType machine_type; // machine type of the field.
71 : WriteBarrierKind write_barrier_kind; // write barrier hint.
72 :
73 8006126 : int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
74 : };
75 :
76 : V8_EXPORT_PRIVATE bool operator==(FieldAccess const&, FieldAccess const&);
77 : bool operator!=(FieldAccess const&, FieldAccess const&);
78 :
79 : size_t hash_value(FieldAccess const&);
80 :
81 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, FieldAccess const&);
82 :
83 : FieldAccess const& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT;
84 :
85 : template <>
86 : void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
87 : PrintVerbosity verbose) const;
88 :
89 : // An access descriptor for loads/stores of indexed structures like characters
90 : // in strings or off-heap backing stores. Accesses from either tagged or
91 : // untagged base pointers are supported; untagging is done automatically during
92 : // lowering.
93 : struct ElementAccess {
94 : BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged.
95 : int header_size; // size of the header, without tag.
96 : Type* type; // type of the element.
97 : MachineType machine_type; // machine type of the element.
98 : WriteBarrierKind write_barrier_kind; // write barrier hint.
99 :
100 810041 : int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
101 : };
102 :
103 : V8_EXPORT_PRIVATE bool operator==(ElementAccess const&, ElementAccess const&);
104 : bool operator!=(ElementAccess const&, ElementAccess const&);
105 :
106 : size_t hash_value(ElementAccess const&);
107 :
108 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ElementAccess const&);
109 :
110 : V8_EXPORT_PRIVATE ElementAccess const& ElementAccessOf(const Operator* op)
111 : WARN_UNUSED_RESULT;
112 :
113 : ExternalArrayType ExternalArrayTypeOf(const Operator* op) WARN_UNUSED_RESULT;
114 :
115 : enum class CheckFloat64HoleMode : uint8_t {
116 : kNeverReturnHole, // Never return the hole (deoptimize instead).
117 : kAllowReturnHole // Allow to return the hole (signaling NaN).
118 : };
119 :
120 : size_t hash_value(CheckFloat64HoleMode);
121 :
122 : std::ostream& operator<<(std::ostream&, CheckFloat64HoleMode);
123 :
124 : CheckFloat64HoleMode CheckFloat64HoleModeOf(const Operator*) WARN_UNUSED_RESULT;
125 :
126 : enum class CheckTaggedInputMode : uint8_t {
127 : kNumber,
128 : kNumberOrOddball,
129 : };
130 :
131 : size_t hash_value(CheckTaggedInputMode);
132 :
133 : std::ostream& operator<<(std::ostream&, CheckTaggedInputMode);
134 :
135 : CheckTaggedInputMode CheckTaggedInputModeOf(const Operator*) WARN_UNUSED_RESULT;
136 :
137 : enum class CheckForMinusZeroMode : uint8_t {
138 : kCheckForMinusZero,
139 : kDontCheckForMinusZero,
140 : };
141 :
142 : size_t hash_value(CheckForMinusZeroMode);
143 :
144 : std::ostream& operator<<(std::ostream&, CheckForMinusZeroMode);
145 :
146 : CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator*) WARN_UNUSED_RESULT;
147 :
148 : // Flags for map checks.
149 : enum class CheckMapsFlag : uint8_t {
150 : kNone = 0u,
151 : kTryMigrateInstance = 1u << 0, // Try instance migration.
152 : };
153 : typedef base::Flags<CheckMapsFlag> CheckMapsFlags;
154 :
155 : DEFINE_OPERATORS_FOR_FLAGS(CheckMapsFlags)
156 :
157 : std::ostream& operator<<(std::ostream&, CheckMapsFlags);
158 :
159 : // A descriptor for map checks.
160 : class CheckMapsParameters final {
161 : public:
162 : CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps)
163 68681 : : flags_(flags), maps_(maps) {}
164 :
165 : CheckMapsFlags flags() const { return flags_; }
166 : ZoneHandleSet<Map> const& maps() const { return maps_; }
167 :
168 : private:
169 : CheckMapsFlags const flags_;
170 : ZoneHandleSet<Map> const maps_;
171 : };
172 :
173 : bool operator==(CheckMapsParameters const&, CheckMapsParameters const&);
174 : bool operator!=(CheckMapsParameters const&, CheckMapsParameters const&);
175 :
176 : size_t hash_value(CheckMapsParameters const&);
177 :
178 : std::ostream& operator<<(std::ostream&, CheckMapsParameters const&);
179 :
180 : CheckMapsParameters const& CheckMapsParametersOf(Operator const*)
181 : WARN_UNUSED_RESULT;
182 :
183 : // A descriptor for growing elements backing stores.
184 : enum class GrowFastElementsFlag : uint8_t {
185 : kNone = 0u,
186 : kArrayObject = 1u << 0, // Update JSArray::length field.
187 : kHoleyElements = 1u << 1, // Backing store is holey.
188 : kDoubleElements = 1u << 2, // Backing store contains doubles.
189 : };
190 : typedef base::Flags<GrowFastElementsFlag> GrowFastElementsFlags;
191 :
192 : DEFINE_OPERATORS_FOR_FLAGS(GrowFastElementsFlags)
193 :
194 : std::ostream& operator<<(std::ostream&, GrowFastElementsFlags);
195 :
196 : GrowFastElementsFlags GrowFastElementsFlagsOf(const Operator*)
197 : WARN_UNUSED_RESULT;
198 :
199 : // A descriptor for elements kind transitions.
200 : class ElementsTransition final {
201 : public:
202 : enum Mode : uint8_t {
203 : kFastTransition, // simple transition, just updating the map.
204 : kSlowTransition // full transition, round-trip to the runtime.
205 : };
206 :
207 : ElementsTransition(Mode mode, Handle<Map> source, Handle<Map> target)
208 433 : : mode_(mode), source_(source), target_(target) {}
209 :
210 : Mode mode() const { return mode_; }
211 : Handle<Map> source() const { return source_; }
212 : Handle<Map> target() const { return target_; }
213 :
214 : private:
215 : Mode const mode_;
216 : Handle<Map> const source_;
217 : Handle<Map> const target_;
218 : };
219 :
220 : bool operator==(ElementsTransition const&, ElementsTransition const&);
221 : bool operator!=(ElementsTransition const&, ElementsTransition const&);
222 :
223 : size_t hash_value(ElementsTransition);
224 :
225 : std::ostream& operator<<(std::ostream&, ElementsTransition);
226 :
227 : ElementsTransition const& ElementsTransitionOf(const Operator* op)
228 : WARN_UNUSED_RESULT;
229 :
230 : // A hint for speculative number operations.
231 : enum class NumberOperationHint : uint8_t {
232 : kSignedSmall, // Inputs were always Smi so far, output was in Smi range.
233 : kSigned32, // Inputs and output were Signed32 so far.
234 : kNumber, // Inputs were Number, output was Number.
235 : kNumberOrOddball, // Inputs were Number or Oddball, output was Number.
236 : };
237 :
238 : size_t hash_value(NumberOperationHint);
239 :
240 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, NumberOperationHint);
241 :
242 : NumberOperationHint NumberOperationHintOf(const Operator* op)
243 : WARN_UNUSED_RESULT;
244 :
245 : int FormalParameterCountOf(const Operator* op) WARN_UNUSED_RESULT;
246 : bool IsRestLengthOf(const Operator* op) WARN_UNUSED_RESULT;
247 :
248 : class AllocateParameters {
249 : public:
250 : AllocateParameters(Type* type, PretenureFlag pretenure)
251 : : type_(type), pretenure_(pretenure) {}
252 :
253 : Type* type() const { return type_; }
254 : PretenureFlag pretenure() const { return pretenure_; }
255 :
256 : private:
257 : Type* type_;
258 : PretenureFlag pretenure_;
259 : };
260 :
261 : size_t hash_value(AllocateParameters);
262 :
263 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, AllocateParameters);
264 :
265 : bool operator==(AllocateParameters const&, AllocateParameters const&);
266 : bool operator!=(AllocateParameters const&, AllocateParameters const&);
267 :
268 : PretenureFlag PretenureFlagOf(const Operator* op) WARN_UNUSED_RESULT;
269 :
270 : Type* AllocateTypeOf(const Operator* op) WARN_UNUSED_RESULT;
271 :
272 : UnicodeEncoding UnicodeEncodingOf(const Operator*) WARN_UNUSED_RESULT;
273 :
274 : // Interface for building simplified operators, which represent the
275 : // medium-level operations of V8, including adding numbers, allocating objects,
276 : // indexing into objects and arrays, etc.
277 : // All operators are typed but many are representation independent.
278 :
279 : // Number values from JS can be in one of these representations:
280 : // - Tagged: word-sized integer that is either
281 : // - a signed small integer (31 or 32 bits plus a tag)
282 : // - a tagged pointer to a HeapNumber object that has a float64 field
283 : // - Int32: an untagged signed 32-bit integer
284 : // - Uint32: an untagged unsigned 32-bit integer
285 : // - Float64: an untagged float64
286 :
287 : // Additional representations for intermediate code or non-JS code:
288 : // - Int64: an untagged signed 64-bit integer
289 : // - Uint64: an untagged unsigned 64-bit integer
290 : // - Float32: an untagged float32
291 :
292 : // Boolean values can be:
293 : // - Bool: a tagged pointer to either the canonical JS #false or
294 : // the canonical JS #true object
295 : // - Bit: an untagged integer 0 or 1, but word-sized
296 : class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
297 : : public NON_EXPORTED_BASE(ZoneObject) {
298 : public:
299 : explicit SimplifiedOperatorBuilder(Zone* zone);
300 :
301 : const Operator* BooleanNot();
302 :
303 : const Operator* NumberEqual();
304 : const Operator* NumberLessThan();
305 : const Operator* NumberLessThanOrEqual();
306 : const Operator* NumberAdd();
307 : const Operator* NumberSubtract();
308 : const Operator* NumberMultiply();
309 : const Operator* NumberDivide();
310 : const Operator* NumberModulus();
311 : const Operator* NumberBitwiseOr();
312 : const Operator* NumberBitwiseXor();
313 : const Operator* NumberBitwiseAnd();
314 : const Operator* NumberShiftLeft();
315 : const Operator* NumberShiftRight();
316 : const Operator* NumberShiftRightLogical();
317 : const Operator* NumberImul();
318 : const Operator* NumberAbs();
319 : const Operator* NumberClz32();
320 : const Operator* NumberCeil();
321 : const Operator* NumberFloor();
322 : const Operator* NumberFround();
323 : const Operator* NumberAcos();
324 : const Operator* NumberAcosh();
325 : const Operator* NumberAsin();
326 : const Operator* NumberAsinh();
327 : const Operator* NumberAtan();
328 : const Operator* NumberAtan2();
329 : const Operator* NumberAtanh();
330 : const Operator* NumberCbrt();
331 : const Operator* NumberCos();
332 : const Operator* NumberCosh();
333 : const Operator* NumberExp();
334 : const Operator* NumberExpm1();
335 : const Operator* NumberLog();
336 : const Operator* NumberLog1p();
337 : const Operator* NumberLog10();
338 : const Operator* NumberLog2();
339 : const Operator* NumberMax();
340 : const Operator* NumberMin();
341 : const Operator* NumberPow();
342 : const Operator* NumberRound();
343 : const Operator* NumberSign();
344 : const Operator* NumberSin();
345 : const Operator* NumberSinh();
346 : const Operator* NumberSqrt();
347 : const Operator* NumberTan();
348 : const Operator* NumberTanh();
349 : const Operator* NumberTrunc();
350 : const Operator* NumberToBoolean();
351 : const Operator* NumberToInt32();
352 : const Operator* NumberToUint32();
353 : const Operator* NumberToUint8Clamped();
354 :
355 : const Operator* NumberSilenceNaN();
356 :
357 : const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
358 : const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
359 : const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
360 : const Operator* SpeculativeNumberDivide(NumberOperationHint hint);
361 : const Operator* SpeculativeNumberModulus(NumberOperationHint hint);
362 : const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint);
363 : const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint);
364 : const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint);
365 : const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint);
366 : const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint);
367 : const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint);
368 :
369 : const Operator* SpeculativeNumberLessThan(NumberOperationHint hint);
370 : const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint);
371 : const Operator* SpeculativeNumberEqual(NumberOperationHint hint);
372 :
373 : const Operator* ReferenceEqual();
374 :
375 : const Operator* StringEqual();
376 : const Operator* StringLessThan();
377 : const Operator* StringLessThanOrEqual();
378 : const Operator* StringCharAt();
379 : const Operator* StringCharCodeAt();
380 : const Operator* StringFromCharCode();
381 : const Operator* StringFromCodePoint(UnicodeEncoding encoding);
382 : const Operator* StringIndexOf();
383 :
384 : const Operator* SpeculativeToNumber(NumberOperationHint hint);
385 :
386 : const Operator* PlainPrimitiveToNumber();
387 : const Operator* PlainPrimitiveToWord32();
388 : const Operator* PlainPrimitiveToFloat64();
389 :
390 : const Operator* ChangeTaggedSignedToInt32();
391 : const Operator* ChangeTaggedToInt32();
392 : const Operator* ChangeTaggedToUint32();
393 : const Operator* ChangeTaggedToFloat64();
394 : const Operator* ChangeTaggedToTaggedSigned();
395 : const Operator* ChangeInt31ToTaggedSigned();
396 : const Operator* ChangeInt32ToTagged();
397 : const Operator* ChangeUint32ToTagged();
398 : const Operator* ChangeFloat64ToTagged(CheckForMinusZeroMode);
399 : const Operator* ChangeFloat64ToTaggedPointer();
400 : const Operator* ChangeTaggedToBit();
401 : const Operator* ChangeBitToTagged();
402 : const Operator* TruncateTaggedToWord32();
403 : const Operator* TruncateTaggedToFloat64();
404 : const Operator* TruncateTaggedToBit();
405 : const Operator* TruncateTaggedPointerToBit();
406 :
407 : const Operator* CheckIf();
408 : const Operator* CheckBounds();
409 : const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>);
410 :
411 : const Operator* CheckHeapObject();
412 : const Operator* CheckInternalizedString();
413 : const Operator* CheckNumber();
414 : const Operator* CheckSmi();
415 : const Operator* CheckString();
416 : const Operator* CheckReceiver();
417 :
418 : const Operator* CheckedInt32Add();
419 : const Operator* CheckedInt32Sub();
420 : const Operator* CheckedInt32Div();
421 : const Operator* CheckedInt32Mod();
422 : const Operator* CheckedUint32Div();
423 : const Operator* CheckedUint32Mod();
424 : const Operator* CheckedInt32Mul(CheckForMinusZeroMode);
425 : const Operator* CheckedInt32ToTaggedSigned();
426 : const Operator* CheckedUint32ToInt32();
427 : const Operator* CheckedUint32ToTaggedSigned();
428 : const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode);
429 : const Operator* CheckedTaggedSignedToInt32();
430 : const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode);
431 : const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode);
432 : const Operator* CheckedTaggedToTaggedSigned();
433 : const Operator* CheckedTaggedToTaggedPointer();
434 : const Operator* CheckedTruncateTaggedToWord32();
435 :
436 : const Operator* CheckFloat64Hole(CheckFloat64HoleMode);
437 : const Operator* CheckTaggedHole();
438 : const Operator* ConvertTaggedHoleToUndefined();
439 :
440 : const Operator* ObjectIsDetectableCallable();
441 : const Operator* ObjectIsNaN();
442 : const Operator* ObjectIsNonCallable();
443 : const Operator* ObjectIsNumber();
444 : const Operator* ObjectIsReceiver();
445 : const Operator* ObjectIsSmi();
446 : const Operator* ObjectIsString();
447 : const Operator* ObjectIsSymbol();
448 : const Operator* ObjectIsUndetectable();
449 :
450 : const Operator* ArgumentsFrame();
451 : const Operator* ArgumentsLength(int formal_parameter_count,
452 : bool is_rest_length);
453 :
454 : // new-unmapped-arguments-elements
455 : const Operator* NewUnmappedArgumentsElements();
456 :
457 : // array-buffer-was-neutered buffer
458 : const Operator* ArrayBufferWasNeutered();
459 :
460 : // ensure-writable-fast-elements object, elements
461 : const Operator* EnsureWritableFastElements();
462 :
463 : // maybe-grow-fast-elements object, elements, index, length
464 : const Operator* MaybeGrowFastElements(GrowFastElementsFlags flags);
465 :
466 : // transition-elements-kind object, from-map, to-map
467 : const Operator* TransitionElementsKind(ElementsTransition transition);
468 :
469 : const Operator* Allocate(Type* type, PretenureFlag pretenure = NOT_TENURED);
470 :
471 : const Operator* LoadField(FieldAccess const&);
472 : const Operator* StoreField(FieldAccess const&);
473 :
474 : // load-buffer buffer, offset, length
475 : const Operator* LoadBuffer(BufferAccess);
476 :
477 : // store-buffer buffer, offset, length, value
478 : const Operator* StoreBuffer(BufferAccess);
479 :
480 : // load-element [base + index]
481 : const Operator* LoadElement(ElementAccess const&);
482 :
483 : // store-element [base + index], value
484 : const Operator* StoreElement(ElementAccess const&);
485 :
486 : // load-typed-element buffer, [base + external + index]
487 : const Operator* LoadTypedElement(ExternalArrayType const&);
488 :
489 : // store-typed-element buffer, [base + external + index], value
490 : const Operator* StoreTypedElement(ExternalArrayType const&);
491 :
492 : private:
493 : Zone* zone() const { return zone_; }
494 :
495 : const SimplifiedOperatorGlobalCache& cache_;
496 : Zone* const zone_;
497 :
498 : DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder);
499 : };
500 :
501 : } // namespace compiler
502 : } // namespace internal
503 : } // namespace v8
504 :
505 : #endif // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
|