Home | History | Annotate | Download | only in compiler
      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();
     25   VectorSlotPair(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
     26       : vector_(vector), slot_(slot) {}
     27 
     28   bool IsValid() const { return !vector_.is_null() && !slot_.IsInvalid(); }
     29 
     30   Handle<TypeFeedbackVector> vector() const { return vector_; }
     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:
     66   BinaryOperationParameters(LanguageMode language_mode,
     67                             BinaryOperationHints hints)
     68       : language_mode_(language_mode), hints_(hints) {}
     69 
     70   LanguageMode language_mode() const { return language_mode_; }
     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:
     94   CallConstructParameters(size_t arity, VectorSlotPair const& feedback)
     95       : arity_(arity), feedback_(feedback) {}
     96 
     97   size_t arity() const { return arity_; }
     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:
    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 
    129   size_t arity() const { return ArityField::decode(bit_field_); }
    130   LanguageMode language_mode() const {
    131     return LanguageModeField::decode(bit_field_);
    132   }
    133   ConvertReceiverMode convert_mode() const {
    134     return ConvertReceiverModeField::decode(bit_field_);
    135   }
    136   TailCallMode tail_call_mode() const {
    137     return TailCallModeField::decode(bit_field_);
    138   }
    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:
    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:
    174   CallRuntimeParameters(Runtime::FunctionId id, size_t arity)
    175       : id_(id), arity_(arity) {}
    176 
    177   Runtime::FunctionId id() const { return id_; }
    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 
    202   size_t depth() const { return depth_; }
    203   size_t index() const { return index_; }
    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 
    230   const Handle<String>& name() const { return name_; }
    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:
    252   NamedAccess(LanguageMode language_mode, Handle<Name> name,
    253               VectorSlotPair const& feedback)
    254       : name_(name), feedback_(feedback), language_mode_(language_mode) {}
    255 
    256   Handle<Name> name() const { return name_; }
    257   LanguageMode language_mode() const { return language_mode_; }
    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:
    280   LoadGlobalParameters(const Handle<Name>& name, const VectorSlotPair& feedback,
    281                        TypeofMode typeof_mode)
    282       : name_(name), feedback_(feedback), typeof_mode_(typeof_mode) {}
    283 
    284   const Handle<Name>& name() const { return name_; }
    285   TypeofMode typeof_mode() const { return typeof_mode_; }
    286 
    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:
    309   StoreGlobalParameters(LanguageMode language_mode,
    310                         const VectorSlotPair& feedback,
    311                         const Handle<Name>& name)
    312       : language_mode_(language_mode), name_(name), feedback_(feedback) {}
    313 
    314   LanguageMode language_mode() const { return language_mode_; }
    315   const VectorSlotPair& feedback() const { return feedback_; }
    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:
    338   PropertyAccess(LanguageMode language_mode, VectorSlotPair const& feedback)
    339       : feedback_(feedback), language_mode_(language_mode) {}
    340 
    341   LanguageMode language_mode() const { return language_mode_; }
    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 };
    364   CreateArgumentsParameters(Type type, int start_index)
    365       : type_(type), start_index_(start_index) {}
    366 
    367   Type type() const { return type_; }
    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:
    392   explicit CreateArrayParameters(size_t arity, Handle<AllocationSite> site)
    393       : arity_(arity), site_(site) {}
    394 
    395   size_t arity() const { return arity_; }
    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:
    417   CreateClosureParameters(Handle<SharedFunctionInfo> shared_info,
    418                           PretenureFlag pretenure)
    419       : shared_info_(shared_info), pretenure_(pretenure) {}
    420 
    421   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
    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:
    444   CreateLiteralParameters(Handle<HeapObject> constant, int flags, int index)
    445       : constant_(constant), flags_(flags), index_(index) {}
    446 
    447   Handle<HeapObject> constant() const { return constant_; }
    448   int flags() const { return flags_; }
    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:
    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