• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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_JS_OPERATOR_H_
6 #define V8_COMPILER_JS_OPERATOR_H_
7 
8 #include "src/compiler/type-hints.h"
9 #include "src/runtime/runtime.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14 
15 // Forward declarations.
16 class Operator;
17 struct JSOperatorGlobalCache;
18 
19 
20 // Defines a pair of {TypeFeedbackVector} and {TypeFeedbackVectorSlot}, which
21 // is used to access the type feedback for a certain {Node}.
22 class VectorSlotPair {
23  public:
24   VectorSlotPair();
VectorSlotPair(Handle<TypeFeedbackVector> vector,FeedbackVectorSlot slot)25   VectorSlotPair(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
26       : vector_(vector), slot_(slot) {}
27 
IsValid()28   bool IsValid() const { return !vector_.is_null() && !slot_.IsInvalid(); }
29 
vector()30   Handle<TypeFeedbackVector> vector() const { return vector_; }
slot()31   FeedbackVectorSlot slot() const { return slot_; }
32 
33   int index() const;
34 
35  private:
36   const Handle<TypeFeedbackVector> vector_;
37   const FeedbackVectorSlot slot_;
38 };
39 
40 bool operator==(VectorSlotPair const&, VectorSlotPair const&);
41 bool operator!=(VectorSlotPair const&, VectorSlotPair const&);
42 
43 size_t hash_value(VectorSlotPair const&);
44 
45 
46 // The ConvertReceiverMode is used as parameter by JSConvertReceiver operators.
47 ConvertReceiverMode ConvertReceiverModeOf(Operator const* op);
48 
49 
50 // The ToBooleanHints are used as parameter by JSToBoolean operators.
51 ToBooleanHints ToBooleanHintsOf(Operator const* op);
52 
53 
54 // Defines whether tail call optimization is allowed.
55 enum class TailCallMode : unsigned { kAllow, kDisallow };
56 
57 size_t hash_value(TailCallMode);
58 
59 std::ostream& operator<<(std::ostream&, TailCallMode);
60 
61 
62 // Defines the language mode and hints for a JavaScript binary operations.
63 // This is used as parameter by JSAdd, JSSubtract, etc. operators.
64 class BinaryOperationParameters final {
65  public:
BinaryOperationParameters(LanguageMode language_mode,BinaryOperationHints hints)66   BinaryOperationParameters(LanguageMode language_mode,
67                             BinaryOperationHints hints)
68       : language_mode_(language_mode), hints_(hints) {}
69 
language_mode()70   LanguageMode language_mode() const { return language_mode_; }
hints()71   BinaryOperationHints hints() const { return hints_; }
72 
73  private:
74   LanguageMode const language_mode_;
75   BinaryOperationHints const hints_;
76 };
77 
78 bool operator==(BinaryOperationParameters const&,
79                 BinaryOperationParameters const&);
80 bool operator!=(BinaryOperationParameters const&,
81                 BinaryOperationParameters const&);
82 
83 size_t hash_value(BinaryOperationParameters const&);
84 
85 std::ostream& operator<<(std::ostream&, BinaryOperationParameters const&);
86 
87 BinaryOperationParameters const& BinaryOperationParametersOf(Operator const*);
88 
89 
90 // Defines the arity and the feedback for a JavaScript constructor call. This is
91 // used as a parameter by JSCallConstruct operators.
92 class CallConstructParameters final {
93  public:
CallConstructParameters(size_t arity,VectorSlotPair const & feedback)94   CallConstructParameters(size_t arity, VectorSlotPair const& feedback)
95       : arity_(arity), feedback_(feedback) {}
96 
arity()97   size_t arity() const { return arity_; }
feedback()98   VectorSlotPair const& feedback() const { return feedback_; }
99 
100  private:
101   size_t const arity_;
102   VectorSlotPair const feedback_;
103 };
104 
105 bool operator==(CallConstructParameters const&, CallConstructParameters const&);
106 bool operator!=(CallConstructParameters const&, CallConstructParameters const&);
107 
108 size_t hash_value(CallConstructParameters const&);
109 
110 std::ostream& operator<<(std::ostream&, CallConstructParameters const&);
111 
112 CallConstructParameters const& CallConstructParametersOf(Operator const*);
113 
114 
115 // Defines the arity and the call flags for a JavaScript function call. This is
116 // used as a parameter by JSCallFunction operators.
117 class CallFunctionParameters final {
118  public:
CallFunctionParameters(size_t arity,LanguageMode language_mode,VectorSlotPair const & feedback,TailCallMode tail_call_mode,ConvertReceiverMode convert_mode)119   CallFunctionParameters(size_t arity, LanguageMode language_mode,
120                          VectorSlotPair const& feedback,
121                          TailCallMode tail_call_mode,
122                          ConvertReceiverMode convert_mode)
123       : bit_field_(ArityField::encode(arity) |
124                    ConvertReceiverModeField::encode(convert_mode) |
125                    LanguageModeField::encode(language_mode) |
126                    TailCallModeField::encode(tail_call_mode)),
127         feedback_(feedback) {}
128 
arity()129   size_t arity() const { return ArityField::decode(bit_field_); }
language_mode()130   LanguageMode language_mode() const {
131     return LanguageModeField::decode(bit_field_);
132   }
convert_mode()133   ConvertReceiverMode convert_mode() const {
134     return ConvertReceiverModeField::decode(bit_field_);
135   }
tail_call_mode()136   TailCallMode tail_call_mode() const {
137     return TailCallModeField::decode(bit_field_);
138   }
feedback()139   VectorSlotPair const& feedback() const { return feedback_; }
140 
141   bool operator==(CallFunctionParameters const& that) const {
142     return this->bit_field_ == that.bit_field_ &&
143            this->feedback_ == that.feedback_;
144   }
145   bool operator!=(CallFunctionParameters const& that) const {
146     return !(*this == that);
147   }
148 
149  private:
hash_value(CallFunctionParameters const & p)150   friend size_t hash_value(CallFunctionParameters const& p) {
151     return base::hash_combine(p.bit_field_, p.feedback_);
152   }
153 
154   typedef BitField<size_t, 0, 27> ArityField;
155   typedef BitField<ConvertReceiverMode, 27, 2> ConvertReceiverModeField;
156   typedef BitField<LanguageMode, 29, 2> LanguageModeField;
157   typedef BitField<TailCallMode, 31, 1> TailCallModeField;
158 
159   const uint32_t bit_field_;
160   const VectorSlotPair feedback_;
161 };
162 
163 size_t hash_value(CallFunctionParameters const&);
164 
165 std::ostream& operator<<(std::ostream&, CallFunctionParameters const&);
166 
167 const CallFunctionParameters& CallFunctionParametersOf(const Operator* op);
168 
169 
170 // Defines the arity and the ID for a runtime function call. This is used as a
171 // parameter by JSCallRuntime operators.
172 class CallRuntimeParameters final {
173  public:
CallRuntimeParameters(Runtime::FunctionId id,size_t arity)174   CallRuntimeParameters(Runtime::FunctionId id, size_t arity)
175       : id_(id), arity_(arity) {}
176 
id()177   Runtime::FunctionId id() const { return id_; }
arity()178   size_t arity() const { return arity_; }
179 
180  private:
181   const Runtime::FunctionId id_;
182   const size_t arity_;
183 };
184 
185 bool operator==(CallRuntimeParameters const&, CallRuntimeParameters const&);
186 bool operator!=(CallRuntimeParameters const&, CallRuntimeParameters const&);
187 
188 size_t hash_value(CallRuntimeParameters const&);
189 
190 std::ostream& operator<<(std::ostream&, CallRuntimeParameters const&);
191 
192 const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op);
193 
194 
195 // Defines the location of a context slot relative to a specific scope. This is
196 // used as a parameter by JSLoadContext and JSStoreContext operators and allows
197 // accessing a context-allocated variable without keeping track of the scope.
198 class ContextAccess final {
199  public:
200   ContextAccess(size_t depth, size_t index, bool immutable);
201 
depth()202   size_t depth() const { return depth_; }
index()203   size_t index() const { return index_; }
immutable()204   bool immutable() const { return immutable_; }
205 
206  private:
207   // For space reasons, we keep this tightly packed, otherwise we could just use
208   // a simple int/int/bool POD.
209   const bool immutable_;
210   const uint16_t depth_;
211   const uint32_t index_;
212 };
213 
214 bool operator==(ContextAccess const&, ContextAccess const&);
215 bool operator!=(ContextAccess const&, ContextAccess const&);
216 
217 size_t hash_value(ContextAccess const&);
218 
219 std::ostream& operator<<(std::ostream&, ContextAccess const&);
220 
221 ContextAccess const& ContextAccessOf(Operator const*);
222 
223 
224 // Defines the name for a dynamic variable lookup. This is used as a parameter
225 // by JSLoadDynamic and JSStoreDynamic operators.
226 class DynamicAccess final {
227  public:
228   DynamicAccess(const Handle<String>& name, TypeofMode typeof_mode);
229 
name()230   const Handle<String>& name() const { return name_; }
typeof_mode()231   TypeofMode typeof_mode() const { return typeof_mode_; }
232 
233  private:
234   const Handle<String> name_;
235   const TypeofMode typeof_mode_;
236 };
237 
238 size_t hash_value(DynamicAccess const&);
239 
240 bool operator==(DynamicAccess const&, DynamicAccess const&);
241 bool operator!=(DynamicAccess const&, DynamicAccess const&);
242 
243 std::ostream& operator<<(std::ostream&, DynamicAccess const&);
244 
245 DynamicAccess const& DynamicAccessOf(Operator const*);
246 
247 
248 // Defines the property of an object for a named access. This is
249 // used as a parameter by the JSLoadNamed and JSStoreNamed operators.
250 class NamedAccess final {
251  public:
NamedAccess(LanguageMode language_mode,Handle<Name> name,VectorSlotPair const & feedback)252   NamedAccess(LanguageMode language_mode, Handle<Name> name,
253               VectorSlotPair const& feedback)
254       : name_(name), feedback_(feedback), language_mode_(language_mode) {}
255 
name()256   Handle<Name> name() const { return name_; }
language_mode()257   LanguageMode language_mode() const { return language_mode_; }
feedback()258   VectorSlotPair const& feedback() const { return feedback_; }
259 
260  private:
261   Handle<Name> const name_;
262   VectorSlotPair const feedback_;
263   LanguageMode const language_mode_;
264 };
265 
266 bool operator==(NamedAccess const&, NamedAccess const&);
267 bool operator!=(NamedAccess const&, NamedAccess const&);
268 
269 size_t hash_value(NamedAccess const&);
270 
271 std::ostream& operator<<(std::ostream&, NamedAccess const&);
272 
273 const NamedAccess& NamedAccessOf(const Operator* op);
274 
275 
276 // Defines the property being loaded from an object by a named load. This is
277 // used as a parameter by JSLoadGlobal operator.
278 class LoadGlobalParameters final {
279  public:
LoadGlobalParameters(const Handle<Name> & name,const VectorSlotPair & feedback,TypeofMode typeof_mode)280   LoadGlobalParameters(const Handle<Name>& name, const VectorSlotPair& feedback,
281                        TypeofMode typeof_mode)
282       : name_(name), feedback_(feedback), typeof_mode_(typeof_mode) {}
283 
name()284   const Handle<Name>& name() const { return name_; }
typeof_mode()285   TypeofMode typeof_mode() const { return typeof_mode_; }
286 
feedback()287   const VectorSlotPair& feedback() const { return feedback_; }
288 
289  private:
290   const Handle<Name> name_;
291   const VectorSlotPair feedback_;
292   const TypeofMode typeof_mode_;
293 };
294 
295 bool operator==(LoadGlobalParameters const&, LoadGlobalParameters const&);
296 bool operator!=(LoadGlobalParameters const&, LoadGlobalParameters const&);
297 
298 size_t hash_value(LoadGlobalParameters const&);
299 
300 std::ostream& operator<<(std::ostream&, LoadGlobalParameters const&);
301 
302 const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op);
303 
304 
305 // Defines the property being stored to an object by a named store. This is
306 // used as a parameter by JSStoreGlobal operator.
307 class StoreGlobalParameters final {
308  public:
StoreGlobalParameters(LanguageMode language_mode,const VectorSlotPair & feedback,const Handle<Name> & name)309   StoreGlobalParameters(LanguageMode language_mode,
310                         const VectorSlotPair& feedback,
311                         const Handle<Name>& name)
312       : language_mode_(language_mode), name_(name), feedback_(feedback) {}
313 
language_mode()314   LanguageMode language_mode() const { return language_mode_; }
feedback()315   const VectorSlotPair& feedback() const { return feedback_; }
name()316   const Handle<Name>& name() const { return name_; }
317 
318  private:
319   const LanguageMode language_mode_;
320   const Handle<Name> name_;
321   const VectorSlotPair feedback_;
322 };
323 
324 bool operator==(StoreGlobalParameters const&, StoreGlobalParameters const&);
325 bool operator!=(StoreGlobalParameters const&, StoreGlobalParameters const&);
326 
327 size_t hash_value(StoreGlobalParameters const&);
328 
329 std::ostream& operator<<(std::ostream&, StoreGlobalParameters const&);
330 
331 const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op);
332 
333 
334 // Defines the property of an object for a keyed access. This is used
335 // as a parameter by the JSLoadProperty and JSStoreProperty operators.
336 class PropertyAccess final {
337  public:
PropertyAccess(LanguageMode language_mode,VectorSlotPair const & feedback)338   PropertyAccess(LanguageMode language_mode, VectorSlotPair const& feedback)
339       : feedback_(feedback), language_mode_(language_mode) {}
340 
language_mode()341   LanguageMode language_mode() const { return language_mode_; }
feedback()342   VectorSlotPair const& feedback() const { return feedback_; }
343 
344  private:
345   VectorSlotPair const feedback_;
346   LanguageMode const language_mode_;
347 };
348 
349 bool operator==(PropertyAccess const&, PropertyAccess const&);
350 bool operator!=(PropertyAccess const&, PropertyAccess const&);
351 
352 size_t hash_value(PropertyAccess const&);
353 
354 std::ostream& operator<<(std::ostream&, PropertyAccess const&);
355 
356 PropertyAccess const& PropertyAccessOf(const Operator* op);
357 
358 
359 // Defines specifics about arguments object or rest parameter creation. This is
360 // used as a parameter by JSCreateArguments operators.
361 class CreateArgumentsParameters final {
362  public:
363   enum Type { kMappedArguments, kUnmappedArguments, kRestArray };
CreateArgumentsParameters(Type type,int start_index)364   CreateArgumentsParameters(Type type, int start_index)
365       : type_(type), start_index_(start_index) {}
366 
type()367   Type type() const { return type_; }
start_index()368   int start_index() const { return start_index_; }
369 
370  private:
371   const Type type_;
372   const int start_index_;
373 };
374 
375 bool operator==(CreateArgumentsParameters const&,
376                 CreateArgumentsParameters const&);
377 bool operator!=(CreateArgumentsParameters const&,
378                 CreateArgumentsParameters const&);
379 
380 size_t hash_value(CreateArgumentsParameters const&);
381 
382 std::ostream& operator<<(std::ostream&, CreateArgumentsParameters const&);
383 
384 const CreateArgumentsParameters& CreateArgumentsParametersOf(
385     const Operator* op);
386 
387 
388 // Defines shared information for the array that should be created. This is
389 // used as parameter by JSCreateArray operators.
390 class CreateArrayParameters final {
391  public:
CreateArrayParameters(size_t arity,Handle<AllocationSite> site)392   explicit CreateArrayParameters(size_t arity, Handle<AllocationSite> site)
393       : arity_(arity), site_(site) {}
394 
arity()395   size_t arity() const { return arity_; }
site()396   Handle<AllocationSite> site() const { return site_; }
397 
398  private:
399   size_t const arity_;
400   Handle<AllocationSite> const site_;
401 };
402 
403 bool operator==(CreateArrayParameters const&, CreateArrayParameters const&);
404 bool operator!=(CreateArrayParameters const&, CreateArrayParameters const&);
405 
406 size_t hash_value(CreateArrayParameters const&);
407 
408 std::ostream& operator<<(std::ostream&, CreateArrayParameters const&);
409 
410 const CreateArrayParameters& CreateArrayParametersOf(const Operator* op);
411 
412 
413 // Defines shared information for the closure that should be created. This is
414 // used as a parameter by JSCreateClosure operators.
415 class CreateClosureParameters final {
416  public:
CreateClosureParameters(Handle<SharedFunctionInfo> shared_info,PretenureFlag pretenure)417   CreateClosureParameters(Handle<SharedFunctionInfo> shared_info,
418                           PretenureFlag pretenure)
419       : shared_info_(shared_info), pretenure_(pretenure) {}
420 
shared_info()421   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
pretenure()422   PretenureFlag pretenure() const { return pretenure_; }
423 
424  private:
425   const Handle<SharedFunctionInfo> shared_info_;
426   const PretenureFlag pretenure_;
427 };
428 
429 bool operator==(CreateClosureParameters const&, CreateClosureParameters const&);
430 bool operator!=(CreateClosureParameters const&, CreateClosureParameters const&);
431 
432 size_t hash_value(CreateClosureParameters const&);
433 
434 std::ostream& operator<<(std::ostream&, CreateClosureParameters const&);
435 
436 const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
437 
438 
439 // Defines shared information for the literal that should be created. This is
440 // used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and
441 // JSCreateLiteralRegExp operators.
442 class CreateLiteralParameters final {
443  public:
CreateLiteralParameters(Handle<HeapObject> constant,int flags,int index)444   CreateLiteralParameters(Handle<HeapObject> constant, int flags, int index)
445       : constant_(constant), flags_(flags), index_(index) {}
446 
constant()447   Handle<HeapObject> constant() const { return constant_; }
flags()448   int flags() const { return flags_; }
index()449   int index() const { return index_; }
450 
451  private:
452   Handle<HeapObject> const constant_;
453   int const flags_;
454   int const index_;
455 };
456 
457 bool operator==(CreateLiteralParameters const&, CreateLiteralParameters const&);
458 bool operator!=(CreateLiteralParameters const&, CreateLiteralParameters const&);
459 
460 size_t hash_value(CreateLiteralParameters const&);
461 
462 std::ostream& operator<<(std::ostream&, CreateLiteralParameters const&);
463 
464 const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op);
465 
466 
467 // Interface for building JavaScript-level operators, e.g. directly from the
468 // AST. Most operators have no parameters, thus can be globally shared for all
469 // graphs.
470 class JSOperatorBuilder final : public ZoneObject {
471  public:
472   explicit JSOperatorBuilder(Zone* zone);
473 
474   const Operator* Equal();
475   const Operator* NotEqual();
476   const Operator* StrictEqual();
477   const Operator* StrictNotEqual();
478   const Operator* LessThan(LanguageMode language_mode);
479   const Operator* GreaterThan(LanguageMode language_mode);
480   const Operator* LessThanOrEqual(LanguageMode language_mode);
481   const Operator* GreaterThanOrEqual(LanguageMode language_mode);
482   const Operator* BitwiseOr(LanguageMode language_mode,
483                             BinaryOperationHints hints);
484   const Operator* BitwiseXor(LanguageMode language_mode,
485                              BinaryOperationHints hints);
486   const Operator* BitwiseAnd(LanguageMode language_mode,
487                              BinaryOperationHints hints);
488   const Operator* ShiftLeft(LanguageMode language_mode,
489                             BinaryOperationHints hints);
490   const Operator* ShiftRight(LanguageMode language_mode,
491                              BinaryOperationHints hints);
492   const Operator* ShiftRightLogical(LanguageMode language_mode,
493                                     BinaryOperationHints hints);
494   const Operator* Add(LanguageMode language_mode, BinaryOperationHints hints);
495   const Operator* Subtract(LanguageMode language_mode,
496                            BinaryOperationHints hints);
497   const Operator* Multiply(LanguageMode language_mode,
498                            BinaryOperationHints hints);
499   const Operator* Divide(LanguageMode language_mode,
500                          BinaryOperationHints hints);
501   const Operator* Modulus(LanguageMode language_mode,
502                           BinaryOperationHints hints);
503 
504   const Operator* ToBoolean(ToBooleanHints hints);
505   const Operator* ToNumber();
506   const Operator* ToString();
507   const Operator* ToName();
508   const Operator* ToObject();
509   const Operator* Yield();
510 
511   const Operator* Create();
512   const Operator* CreateArguments(CreateArgumentsParameters::Type type,
513                                   int start_index);
514   const Operator* CreateArray(size_t arity, Handle<AllocationSite> site);
515   const Operator* CreateClosure(Handle<SharedFunctionInfo> shared_info,
516                                 PretenureFlag pretenure);
517   const Operator* CreateIterResultObject();
518   const Operator* CreateLiteralArray(Handle<FixedArray> constant_elements,
519                                      int literal_flags, int literal_index);
520   const Operator* CreateLiteralObject(Handle<FixedArray> constant_properties,
521                                       int literal_flags, int literal_index);
522   const Operator* CreateLiteralRegExp(Handle<String> constant_pattern,
523                                       int literal_flags, int literal_index);
524 
525   const Operator* CallFunction(
526       size_t arity, LanguageMode language_mode,
527       VectorSlotPair const& feedback = VectorSlotPair(),
528       ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny,
529       TailCallMode tail_call_mode = TailCallMode::kDisallow);
530   const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
531   const Operator* CallConstruct(size_t arity, VectorSlotPair const& feedback);
532 
533   const Operator* ConvertReceiver(ConvertReceiverMode convert_mode);
534 
535   const Operator* LoadProperty(LanguageMode language_mode,
536                                VectorSlotPair const& feedback);
537   const Operator* LoadNamed(LanguageMode language_mode, Handle<Name> name,
538                             VectorSlotPair const& feedback);
539 
540   const Operator* StoreProperty(LanguageMode language_mode,
541                                 VectorSlotPair const& feedback);
542   const Operator* StoreNamed(LanguageMode language_mode, Handle<Name> name,
543                              VectorSlotPair const& feedback);
544 
545   const Operator* DeleteProperty(LanguageMode language_mode);
546 
547   const Operator* HasProperty();
548 
549   const Operator* LoadGlobal(const Handle<Name>& name,
550                              const VectorSlotPair& feedback,
551                              TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
552   const Operator* StoreGlobal(LanguageMode language_mode,
553                               const Handle<Name>& name,
554                               const VectorSlotPair& feedback);
555 
556   const Operator* LoadContext(size_t depth, size_t index, bool immutable);
557   const Operator* StoreContext(size_t depth, size_t index);
558 
559   const Operator* LoadDynamic(const Handle<String>& name,
560                               TypeofMode typeof_mode);
561 
562   const Operator* TypeOf();
563   const Operator* InstanceOf();
564 
565   const Operator* ForInDone();
566   const Operator* ForInNext();
567   const Operator* ForInPrepare();
568   const Operator* ForInStep();
569 
570   const Operator* LoadMessage();
571   const Operator* StoreMessage();
572 
573   const Operator* StackCheck();
574 
575   const Operator* CreateFunctionContext(int slot_count);
576   const Operator* CreateCatchContext(const Handle<String>& name);
577   const Operator* CreateWithContext();
578   const Operator* CreateBlockContext(const Handle<ScopeInfo>& scpope_info);
579   const Operator* CreateModuleContext();
580   const Operator* CreateScriptContext(const Handle<ScopeInfo>& scpope_info);
581 
582  private:
zone()583   Zone* zone() const { return zone_; }
584 
585   const JSOperatorGlobalCache& cache_;
586   Zone* const zone_;
587 
588   DISALLOW_COPY_AND_ASSIGN(JSOperatorBuilder);
589 };
590 
591 }  // namespace compiler
592 }  // namespace internal
593 }  // namespace v8
594 
595 #endif  // V8_COMPILER_JS_OPERATOR_H_
596