• 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/compiler/type-hints.h"
11 #include "src/handles.h"
12 #include "src/machine-type.h"
13 #include "src/objects.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 // Forward declarations.
19 class Type;
20 class Zone;
21 
22 
23 namespace compiler {
24 
25 // Forward declarations.
26 class Operator;
27 struct SimplifiedOperatorGlobalCache;
28 
29 enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase };
30 
31 size_t hash_value(BaseTaggedness);
32 
33 std::ostream& operator<<(std::ostream&, BaseTaggedness);
34 
35 
36 // An access descriptor for loads/stores of array buffers.
37 class BufferAccess final {
38  public:
BufferAccess(ExternalArrayType external_array_type)39   explicit BufferAccess(ExternalArrayType external_array_type)
40       : external_array_type_(external_array_type) {}
41 
external_array_type()42   ExternalArrayType external_array_type() const { return external_array_type_; }
43   MachineType machine_type() const;
44 
45  private:
46   ExternalArrayType const external_array_type_;
47 };
48 
49 bool operator==(BufferAccess, BufferAccess);
50 bool operator!=(BufferAccess, BufferAccess);
51 
52 size_t hash_value(BufferAccess);
53 
54 std::ostream& operator<<(std::ostream&, BufferAccess);
55 
56 BufferAccess const BufferAccessOf(const Operator* op) WARN_UNUSED_RESULT;
57 
58 
59 // An access descriptor for loads/stores of fixed structures like field
60 // accesses of heap objects. Accesses from either tagged or untagged base
61 // pointers are supported; untagging is done automatically during lowering.
62 struct FieldAccess {
63   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
64   int offset;                     // offset of the field, without tag.
65   MaybeHandle<Name> name;         // debugging only.
66   Type* type;                     // type of the field.
67   MachineType machine_type;       // machine type of the field.
68   WriteBarrierKind write_barrier_kind;  // write barrier hint.
69 
tagFieldAccess70   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
71 };
72 
73 bool operator==(FieldAccess const&, FieldAccess const&);
74 bool operator!=(FieldAccess const&, FieldAccess const&);
75 
76 size_t hash_value(FieldAccess const&);
77 
78 std::ostream& operator<<(std::ostream&, FieldAccess const&);
79 
80 FieldAccess const& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT;
81 
82 
83 // An access descriptor for loads/stores of indexed structures like characters
84 // in strings or off-heap backing stores. Accesses from either tagged or
85 // untagged base pointers are supported; untagging is done automatically during
86 // lowering.
87 struct ElementAccess {
88   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
89   int header_size;                // size of the header, without tag.
90   Type* type;                     // type of the element.
91   MachineType machine_type;       // machine type of the element.
92   WriteBarrierKind write_barrier_kind;  // write barrier hint.
93 
tagElementAccess94   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
95 };
96 
97 bool operator==(ElementAccess const&, ElementAccess const&);
98 bool operator!=(ElementAccess const&, ElementAccess const&);
99 
100 size_t hash_value(ElementAccess const&);
101 
102 std::ostream& operator<<(std::ostream&, ElementAccess const&);
103 
104 ElementAccess const& ElementAccessOf(const Operator* op) WARN_UNUSED_RESULT;
105 
106 enum class CheckFloat64HoleMode : uint8_t {
107   kNeverReturnHole,  // Never return the hole (deoptimize instead).
108   kAllowReturnHole   // Allow to return the hole (signaling NaN).
109 };
110 
111 size_t hash_value(CheckFloat64HoleMode);
112 
113 std::ostream& operator<<(std::ostream&, CheckFloat64HoleMode);
114 
115 CheckFloat64HoleMode CheckFloat64HoleModeOf(const Operator*) WARN_UNUSED_RESULT;
116 
117 enum class CheckTaggedHoleMode : uint8_t {
118   kNeverReturnHole,        // Never return the hole (deoptimize instead).
119   kConvertHoleToUndefined  // Convert the hole to undefined.
120 };
121 
122 size_t hash_value(CheckTaggedHoleMode);
123 
124 std::ostream& operator<<(std::ostream&, CheckTaggedHoleMode);
125 
126 CheckTaggedHoleMode CheckTaggedHoleModeOf(const Operator*) WARN_UNUSED_RESULT;
127 
128 Type* TypeOf(const Operator* op) WARN_UNUSED_RESULT;
129 
130 BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op);
131 
132 CompareOperationHints::Hint CompareOperationHintOf(const Operator* op);
133 
134 // Interface for building simplified operators, which represent the
135 // medium-level operations of V8, including adding numbers, allocating objects,
136 // indexing into objects and arrays, etc.
137 // All operators are typed but many are representation independent.
138 
139 // Number values from JS can be in one of these representations:
140 //   - Tagged: word-sized integer that is either
141 //     - a signed small integer (31 or 32 bits plus a tag)
142 //     - a tagged pointer to a HeapNumber object that has a float64 field
143 //   - Int32: an untagged signed 32-bit integer
144 //   - Uint32: an untagged unsigned 32-bit integer
145 //   - Float64: an untagged float64
146 
147 // Additional representations for intermediate code or non-JS code:
148 //   - Int64: an untagged signed 64-bit integer
149 //   - Uint64: an untagged unsigned 64-bit integer
150 //   - Float32: an untagged float32
151 
152 // Boolean values can be:
153 //   - Bool: a tagged pointer to either the canonical JS #false or
154 //           the canonical JS #true object
155 //   - Bit: an untagged integer 0 or 1, but word-sized
156 class SimplifiedOperatorBuilder final : public ZoneObject {
157  public:
158   explicit SimplifiedOperatorBuilder(Zone* zone);
159 
160   const Operator* BooleanNot();
161   const Operator* BooleanToNumber();
162 
163   const Operator* NumberEqual();
164   const Operator* NumberLessThan();
165   const Operator* NumberLessThanOrEqual();
166   const Operator* NumberAdd();
167   const Operator* NumberSubtract();
168   const Operator* NumberMultiply();
169   const Operator* NumberDivide();
170   const Operator* NumberModulus();
171   const Operator* NumberBitwiseOr();
172   const Operator* NumberBitwiseXor();
173   const Operator* NumberBitwiseAnd();
174   const Operator* NumberShiftLeft();
175   const Operator* NumberShiftRight();
176   const Operator* NumberShiftRightLogical();
177   const Operator* NumberImul();
178   const Operator* NumberAbs();
179   const Operator* NumberClz32();
180   const Operator* NumberCeil();
181   const Operator* NumberFloor();
182   const Operator* NumberFround();
183   const Operator* NumberAtan();
184   const Operator* NumberAtan2();
185   const Operator* NumberAtanh();
186   const Operator* NumberCbrt();
187   const Operator* NumberCos();
188   const Operator* NumberExp();
189   const Operator* NumberExpm1();
190   const Operator* NumberLog();
191   const Operator* NumberLog1p();
192   const Operator* NumberLog10();
193   const Operator* NumberLog2();
194   const Operator* NumberRound();
195   const Operator* NumberSin();
196   const Operator* NumberSqrt();
197   const Operator* NumberTan();
198   const Operator* NumberTrunc();
199   const Operator* NumberToInt32();
200   const Operator* NumberToUint32();
201 
202   const Operator* NumberSilenceNaN();
203 
204   const Operator* SpeculativeNumberAdd(BinaryOperationHints::Hint hint);
205   const Operator* SpeculativeNumberSubtract(BinaryOperationHints::Hint hint);
206   const Operator* SpeculativeNumberMultiply(BinaryOperationHints::Hint hint);
207   const Operator* SpeculativeNumberDivide(BinaryOperationHints::Hint hint);
208   const Operator* SpeculativeNumberModulus(BinaryOperationHints::Hint hint);
209 
210   const Operator* SpeculativeNumberLessThan(CompareOperationHints::Hint hint);
211   const Operator* SpeculativeNumberLessThanOrEqual(
212       CompareOperationHints::Hint hint);
213   const Operator* SpeculativeNumberEqual(CompareOperationHints::Hint hint);
214 
215   const Operator* ReferenceEqual(Type* type);
216 
217   const Operator* StringEqual();
218   const Operator* StringLessThan();
219   const Operator* StringLessThanOrEqual();
220   const Operator* StringFromCharCode();
221   const Operator* StringToNumber();
222 
223   const Operator* PlainPrimitiveToNumber();
224   const Operator* PlainPrimitiveToWord32();
225   const Operator* PlainPrimitiveToFloat64();
226 
227   const Operator* ChangeTaggedSignedToInt32();
228   const Operator* ChangeTaggedToInt32();
229   const Operator* ChangeTaggedToUint32();
230   const Operator* ChangeTaggedToFloat64();
231   const Operator* ChangeInt31ToTaggedSigned();
232   const Operator* ChangeInt32ToTagged();
233   const Operator* ChangeUint32ToTagged();
234   const Operator* ChangeFloat64ToTagged();
235   const Operator* ChangeTaggedToBit();
236   const Operator* ChangeBitToTagged();
237   const Operator* TruncateTaggedToWord32();
238   const Operator* TruncateTaggedToFloat64();
239 
240   const Operator* CheckBounds();
241   const Operator* CheckTaggedPointer();
242   const Operator* CheckTaggedSigned();
243 
244   const Operator* CheckedInt32Add();
245   const Operator* CheckedInt32Sub();
246   const Operator* CheckedUint32ToInt32();
247   const Operator* CheckedFloat64ToInt32();
248   const Operator* CheckedTaggedToInt32();
249   const Operator* CheckedTaggedToFloat64();
250 
251   const Operator* CheckFloat64Hole(CheckFloat64HoleMode);
252   const Operator* CheckTaggedHole(CheckTaggedHoleMode);
253 
254   const Operator* ObjectIsCallable();
255   const Operator* ObjectIsNumber();
256   const Operator* ObjectIsReceiver();
257   const Operator* ObjectIsSmi();
258   const Operator* ObjectIsString();
259   const Operator* ObjectIsUndetectable();
260 
261   const Operator* TypeGuard(Type* type);
262 
263   const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED);
264 
265   const Operator* LoadField(FieldAccess const&);
266   const Operator* StoreField(FieldAccess const&);
267 
268   // load-buffer buffer, offset, length
269   const Operator* LoadBuffer(BufferAccess);
270 
271   // store-buffer buffer, offset, length, value
272   const Operator* StoreBuffer(BufferAccess);
273 
274   // load-element [base + index], length
275   const Operator* LoadElement(ElementAccess const&);
276 
277   // store-element [base + index], length, value
278   const Operator* StoreElement(ElementAccess const&);
279 
280  private:
zone()281   Zone* zone() const { return zone_; }
282 
283   const SimplifiedOperatorGlobalCache& cache_;
284   Zone* const zone_;
285 
286   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder);
287 };
288 
289 }  // namespace compiler
290 }  // namespace internal
291 }  // namespace v8
292 
293 #endif  // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
294