• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
BufferAccess(ExternalArrayType external_array_type)41   explicit BufferAccess(ExternalArrayType external_array_type)
42       : external_array_type_(external_array_type) {}
43 
external_array_type()44   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 
tagFieldAccess73   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 
tagElementAccess100   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:
CheckMapsParameters(CheckMapsFlags flags,ZoneHandleSet<Map> const & maps)162   CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps)
163       : flags_(flags), maps_(maps) {}
164 
flags()165   CheckMapsFlags flags() const { return flags_; }
maps()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 
ElementsTransition(Mode mode,Handle<Map> source,Handle<Map> target)207   ElementsTransition(Mode mode, Handle<Map> source, Handle<Map> target)
208       : mode_(mode), source_(source), target_(target) {}
209 
mode()210   Mode mode() const { return mode_; }
source()211   Handle<Map> source() const { return source_; }
target()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 ParameterCountOf(const Operator* op) WARN_UNUSED_RESULT;
246 
247 PretenureFlag PretenureFlagOf(const Operator* op) WARN_UNUSED_RESULT;
248 
249 UnicodeEncoding UnicodeEncodingOf(const Operator*) WARN_UNUSED_RESULT;
250 
251 // Interface for building simplified operators, which represent the
252 // medium-level operations of V8, including adding numbers, allocating objects,
253 // indexing into objects and arrays, etc.
254 // All operators are typed but many are representation independent.
255 
256 // Number values from JS can be in one of these representations:
257 //   - Tagged: word-sized integer that is either
258 //     - a signed small integer (31 or 32 bits plus a tag)
259 //     - a tagged pointer to a HeapNumber object that has a float64 field
260 //   - Int32: an untagged signed 32-bit integer
261 //   - Uint32: an untagged unsigned 32-bit integer
262 //   - Float64: an untagged float64
263 
264 // Additional representations for intermediate code or non-JS code:
265 //   - Int64: an untagged signed 64-bit integer
266 //   - Uint64: an untagged unsigned 64-bit integer
267 //   - Float32: an untagged float32
268 
269 // Boolean values can be:
270 //   - Bool: a tagged pointer to either the canonical JS #false or
271 //           the canonical JS #true object
272 //   - Bit: an untagged integer 0 or 1, but word-sized
273 class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
NON_EXPORTED_BASE(ZoneObject)274     : public NON_EXPORTED_BASE(ZoneObject) {
275  public:
276   explicit SimplifiedOperatorBuilder(Zone* zone);
277 
278   const Operator* BooleanNot();
279 
280   const Operator* NumberEqual();
281   const Operator* NumberLessThan();
282   const Operator* NumberLessThanOrEqual();
283   const Operator* NumberAdd();
284   const Operator* NumberSubtract();
285   const Operator* NumberMultiply();
286   const Operator* NumberDivide();
287   const Operator* NumberModulus();
288   const Operator* NumberBitwiseOr();
289   const Operator* NumberBitwiseXor();
290   const Operator* NumberBitwiseAnd();
291   const Operator* NumberShiftLeft();
292   const Operator* NumberShiftRight();
293   const Operator* NumberShiftRightLogical();
294   const Operator* NumberImul();
295   const Operator* NumberAbs();
296   const Operator* NumberClz32();
297   const Operator* NumberCeil();
298   const Operator* NumberFloor();
299   const Operator* NumberFround();
300   const Operator* NumberAcos();
301   const Operator* NumberAcosh();
302   const Operator* NumberAsin();
303   const Operator* NumberAsinh();
304   const Operator* NumberAtan();
305   const Operator* NumberAtan2();
306   const Operator* NumberAtanh();
307   const Operator* NumberCbrt();
308   const Operator* NumberCos();
309   const Operator* NumberCosh();
310   const Operator* NumberExp();
311   const Operator* NumberExpm1();
312   const Operator* NumberLog();
313   const Operator* NumberLog1p();
314   const Operator* NumberLog10();
315   const Operator* NumberLog2();
316   const Operator* NumberMax();
317   const Operator* NumberMin();
318   const Operator* NumberPow();
319   const Operator* NumberRound();
320   const Operator* NumberSign();
321   const Operator* NumberSin();
322   const Operator* NumberSinh();
323   const Operator* NumberSqrt();
324   const Operator* NumberTan();
325   const Operator* NumberTanh();
326   const Operator* NumberTrunc();
327   const Operator* NumberToBoolean();
328   const Operator* NumberToInt32();
329   const Operator* NumberToUint32();
330   const Operator* NumberToUint8Clamped();
331 
332   const Operator* NumberSilenceNaN();
333 
334   const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
335   const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
336   const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
337   const Operator* SpeculativeNumberDivide(NumberOperationHint hint);
338   const Operator* SpeculativeNumberModulus(NumberOperationHint hint);
339   const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint);
340   const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint);
341   const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint);
342   const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint);
343   const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint);
344   const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint);
345 
346   const Operator* SpeculativeNumberLessThan(NumberOperationHint hint);
347   const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint);
348   const Operator* SpeculativeNumberEqual(NumberOperationHint hint);
349 
350   const Operator* ReferenceEqual();
351 
352   const Operator* StringEqual();
353   const Operator* StringLessThan();
354   const Operator* StringLessThanOrEqual();
355   const Operator* StringCharAt();
356   const Operator* StringCharCodeAt();
357   const Operator* StringFromCharCode();
358   const Operator* StringFromCodePoint(UnicodeEncoding encoding);
359   const Operator* StringIndexOf();
360 
361   const Operator* PlainPrimitiveToNumber();
362   const Operator* PlainPrimitiveToWord32();
363   const Operator* PlainPrimitiveToFloat64();
364 
365   const Operator* ChangeTaggedSignedToInt32();
366   const Operator* ChangeTaggedToInt32();
367   const Operator* ChangeTaggedToUint32();
368   const Operator* ChangeTaggedToFloat64();
369   const Operator* ChangeTaggedToTaggedSigned();
370   const Operator* ChangeInt31ToTaggedSigned();
371   const Operator* ChangeInt32ToTagged();
372   const Operator* ChangeUint32ToTagged();
373   const Operator* ChangeFloat64ToTagged();
374   const Operator* ChangeFloat64ToTaggedPointer();
375   const Operator* ChangeTaggedToBit();
376   const Operator* ChangeBitToTagged();
377   const Operator* TruncateTaggedToWord32();
378   const Operator* TruncateTaggedToFloat64();
379   const Operator* TruncateTaggedToBit();
380 
381   const Operator* CheckIf();
382   const Operator* CheckBounds();
383   const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>);
384 
385   const Operator* CheckHeapObject();
386   const Operator* CheckInternalizedString();
387   const Operator* CheckNumber();
388   const Operator* CheckSmi();
389   const Operator* CheckString();
390   const Operator* CheckReceiver();
391 
392   const Operator* CheckedInt32Add();
393   const Operator* CheckedInt32Sub();
394   const Operator* CheckedInt32Div();
395   const Operator* CheckedInt32Mod();
396   const Operator* CheckedUint32Div();
397   const Operator* CheckedUint32Mod();
398   const Operator* CheckedInt32Mul(CheckForMinusZeroMode);
399   const Operator* CheckedInt32ToTaggedSigned();
400   const Operator* CheckedUint32ToInt32();
401   const Operator* CheckedUint32ToTaggedSigned();
402   const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode);
403   const Operator* CheckedTaggedSignedToInt32();
404   const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode);
405   const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode);
406   const Operator* CheckedTaggedToTaggedSigned();
407   const Operator* CheckedTaggedToTaggedPointer();
408   const Operator* CheckedTruncateTaggedToWord32();
409 
410   const Operator* CheckFloat64Hole(CheckFloat64HoleMode);
411   const Operator* CheckTaggedHole();
412   const Operator* ConvertTaggedHoleToUndefined();
413 
414   const Operator* ObjectIsDetectableCallable();
415   const Operator* ObjectIsNonCallable();
416   const Operator* ObjectIsNumber();
417   const Operator* ObjectIsReceiver();
418   const Operator* ObjectIsSmi();
419   const Operator* ObjectIsString();
420   const Operator* ObjectIsUndetectable();
421 
422   // new-rest-parameter-elements
423   const Operator* NewRestParameterElements(int parameter_count);
424 
425   // new-unmapped-arguments-elements
426   const Operator* NewUnmappedArgumentsElements(int parameter_count);
427 
428   // array-buffer-was-neutered buffer
429   const Operator* ArrayBufferWasNeutered();
430 
431   // ensure-writable-fast-elements object, elements
432   const Operator* EnsureWritableFastElements();
433 
434   // maybe-grow-fast-elements object, elements, index, length
435   const Operator* MaybeGrowFastElements(GrowFastElementsFlags flags);
436 
437   // transition-elements-kind object, from-map, to-map
438   const Operator* TransitionElementsKind(ElementsTransition transition);
439 
440   const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED);
441 
442   const Operator* LoadField(FieldAccess const&);
443   const Operator* StoreField(FieldAccess const&);
444 
445   // load-buffer buffer, offset, length
446   const Operator* LoadBuffer(BufferAccess);
447 
448   // store-buffer buffer, offset, length, value
449   const Operator* StoreBuffer(BufferAccess);
450 
451   // load-element [base + index]
452   const Operator* LoadElement(ElementAccess const&);
453 
454   // store-element [base + index], value
455   const Operator* StoreElement(ElementAccess const&);
456 
457   // load-typed-element buffer, [base + external + index]
458   const Operator* LoadTypedElement(ExternalArrayType const&);
459 
460   // store-typed-element buffer, [base + external + index], value
461   const Operator* StoreTypedElement(ExternalArrayType const&);
462 
463  private:
464   Zone* zone() const { return zone_; }
465 
466   const SimplifiedOperatorGlobalCache& cache_;
467   Zone* const zone_;
468 
469   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder);
470 };
471 
472 }  // namespace compiler
473 }  // namespace internal
474 }  // namespace v8
475 
476 #endif  // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
477