LCOV - code coverage report
Current view: top level - src/torque - instructions.h (source / functions) Hit Total Coverage
Test: app.info Lines: 67 98 68.4 %
Date: 2019-03-21 Functions: 73 112 65.2 %

          Line data    Source code
       1             : // Copyright 2018 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_TORQUE_INSTRUCTIONS_H_
       6             : #define V8_TORQUE_INSTRUCTIONS_H_
       7             : 
       8             : #include <memory>
       9             : 
      10             : #include "src/torque/ast.h"
      11             : #include "src/torque/source-positions.h"
      12             : #include "src/torque/types.h"
      13             : #include "src/torque/utils.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : namespace torque {
      18             : 
      19             : class Block;
      20             : class Builtin;
      21             : class ControlFlowGraph;
      22             : class Intrinsic;
      23             : class Macro;
      24             : class NamespaceConstant;
      25             : class RuntimeFunction;
      26             : 
      27             : #define TORQUE_INSTRUCTION_LIST(V)    \
      28             :   V(PeekInstruction)                  \
      29             :   V(PokeInstruction)                  \
      30             :   V(DeleteRangeInstruction)           \
      31             :   V(PushUninitializedInstruction)     \
      32             :   V(PushBuiltinPointerInstruction)    \
      33             :   V(LoadObjectFieldInstruction)       \
      34             :   V(StoreObjectFieldInstruction)      \
      35             :   V(CallCsaMacroInstruction)          \
      36             :   V(CallIntrinsicInstruction)         \
      37             :   V(NamespaceConstantInstruction)     \
      38             :   V(CallCsaMacroAndBranchInstruction) \
      39             :   V(CallBuiltinInstruction)           \
      40             :   V(CallRuntimeInstruction)           \
      41             :   V(CallBuiltinPointerInstruction)    \
      42             :   V(BranchInstruction)                \
      43             :   V(ConstexprBranchInstruction)       \
      44             :   V(GotoInstruction)                  \
      45             :   V(GotoExternalInstruction)          \
      46             :   V(ReturnInstruction)                \
      47             :   V(PrintConstantStringInstruction)   \
      48             :   V(AbortInstruction)                 \
      49             :   V(UnsafeCastInstruction)
      50             : 
      51             : #define TORQUE_INSTRUCTION_BOILERPLATE()                                 \
      52             :   static const InstructionKind kKind;                                    \
      53             :   std::unique_ptr<InstructionBase> Clone() const override;               \
      54             :   void Assign(const InstructionBase& other) override;                    \
      55             :   void TypeInstruction(Stack<const Type*>* stack, ControlFlowGraph* cfg) \
      56             :       const override;
      57             : 
      58             : enum class InstructionKind {
      59             : #define ENUM_ITEM(name) k##name,
      60             :   TORQUE_INSTRUCTION_LIST(ENUM_ITEM)
      61             : #undef ENUM_ITEM
      62             : };
      63             : 
      64      159505 : struct InstructionBase {
      65       78640 :   InstructionBase() : pos(CurrentSourcePosition::Get()) {}
      66             :   virtual std::unique_ptr<InstructionBase> Clone() const = 0;
      67             :   virtual void Assign(const InstructionBase& other) = 0;
      68      198825 :   virtual ~InstructionBase() = default;
      69             : 
      70             :   virtual void TypeInstruction(Stack<const Type*>* stack,
      71             :                                ControlFlowGraph* cfg) const = 0;
      72             :   void InvalidateTransientTypes(Stack<const Type*>* stack) const;
      73        3626 :   virtual bool IsBlockTerminator() const { return false; }
      74           0 :   virtual void AppendSuccessorBlocks(std::vector<Block*>* block_list) const {}
      75             : 
      76             :   SourcePosition pos;
      77             : };
      78             : 
      79      159505 : class Instruction {
      80             :  public:
      81             :   template <class T>
      82       38152 :   Instruction(T instr)  // NOLINT(runtime/explicit)
      83       76304 :       : kind_(T::kKind), instruction_(new T(std::move(instr))) {}
      84             : 
      85             :   template <class T>
      86             :   T& Cast() {
      87             :     DCHECK(Is<T>());
      88             :     return static_cast<T&>(*instruction_);
      89             :   }
      90             : 
      91             :   template <class T>
      92             :   const T& Cast() const {
      93             :     DCHECK(Is<T>());
      94             :     return static_cast<const T&>(*instruction_);
      95             :   }
      96             : 
      97             :   template <class T>
      98             :   bool Is() const {
      99             :     return kind_ == T::kKind;
     100             :   }
     101             : 
     102             :   template <class T>
     103             :   T* DynamicCast() {
     104             :     if (Is<T>()) return &Cast<T>();
     105             :     return nullptr;
     106             :   }
     107             : 
     108             :   template <class T>
     109             :   const T* DynamicCast() const {
     110             :     if (Is<T>()) return &Cast<T>();
     111             :     return nullptr;
     112             :   }
     113             : 
     114             :   Instruction(const Instruction& other) V8_NOEXCEPT
     115      121353 :       : kind_(other.kind_),
     116      242706 :         instruction_(other.instruction_->Clone()) {}
     117             :   Instruction& operator=(const Instruction& other) V8_NOEXCEPT {
     118             :     if (kind_ == other.kind_) {
     119             :       instruction_->Assign(*other.instruction_);
     120             :     } else {
     121             :       kind_ = other.kind_;
     122             :       instruction_ = other.instruction_->Clone();
     123             :     }
     124             :     return *this;
     125             :   }
     126             : 
     127             :   InstructionKind kind() const { return kind_; }
     128             :   const char* Mnemonic() const {
     129             :     switch (kind()) {
     130             : #define ENUM_ITEM(name)          \
     131             :   case InstructionKind::k##name: \
     132             :     return #name;
     133             :       TORQUE_INSTRUCTION_LIST(ENUM_ITEM)
     134             : #undef ENUM_ITEM
     135             :       default:
     136             :         UNREACHABLE();
     137             :     }
     138             :   }
     139             :   void TypeInstruction(Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
     140       39810 :     return instruction_->TypeInstruction(stack, cfg);
     141             :   }
     142             : 
     143             :   InstructionBase* operator->() { return instruction_.get(); }
     144             :   const InstructionBase* operator->() const { return instruction_.get(); }
     145             : 
     146             :  private:
     147             :   InstructionKind kind_;
     148             :   std::unique_ptr<InstructionBase> instruction_;
     149             : };
     150             : 
     151      268571 : struct PeekInstruction : InstructionBase {
     152             :   TORQUE_INSTRUCTION_BOILERPLATE()
     153             : 
     154             :   PeekInstruction(BottomOffset slot, base::Optional<const Type*> widened_type)
     155       16807 :       : slot(slot), widened_type(widened_type) {}
     156             : 
     157             :   BottomOffset slot;
     158             :   base::Optional<const Type*> widened_type;
     159             : };
     160             : 
     161        7981 : struct PokeInstruction : InstructionBase {
     162             :   TORQUE_INSTRUCTION_BOILERPLATE()
     163             : 
     164             :   PokeInstruction(BottomOffset slot, base::Optional<const Type*> widened_type)
     165         584 :       : slot(slot), widened_type(widened_type) {}
     166             : 
     167             :   BottomOffset slot;
     168             :   base::Optional<const Type*> widened_type;
     169             : };
     170             : 
     171             : // Preserve the top {preserved_slots} number of slots, and delete
     172             : // {deleted_slots} number or slots below.
     173      111503 : struct DeleteRangeInstruction : InstructionBase {
     174             :   TORQUE_INSTRUCTION_BOILERPLATE()
     175        8556 :   explicit DeleteRangeInstruction(StackRange range) : range(range) {}
     176             : 
     177             :   StackRange range;
     178             : };
     179             : 
     180        1408 : struct PushUninitializedInstruction : InstructionBase {
     181             :   TORQUE_INSTRUCTION_BOILERPLATE()
     182          89 :   explicit PushUninitializedInstruction(const Type* type) : type(type) {}
     183             : 
     184             :   const Type* type;
     185             : };
     186             : 
     187        2199 : struct PushBuiltinPointerInstruction : InstructionBase {
     188             :   TORQUE_INSTRUCTION_BOILERPLATE()
     189          74 :   PushBuiltinPointerInstruction(std::string external_name, const Type* type)
     190         148 :       : external_name(std::move(external_name)), type(type) {
     191             :     DCHECK(type->IsBuiltinPointerType());
     192          74 :   }
     193             : 
     194             :   std::string external_name;
     195             :   const Type* type;
     196             : };
     197             : 
     198        6230 : struct NamespaceConstantInstruction : InstructionBase {
     199             :   TORQUE_INSTRUCTION_BOILERPLATE()
     200             :   explicit NamespaceConstantInstruction(NamespaceConstant* constant)
     201         349 :       : constant(constant) {}
     202             : 
     203             :   NamespaceConstant* constant;
     204             : };
     205             : 
     206        6150 : struct LoadObjectFieldInstruction : InstructionBase {
     207             :   TORQUE_INSTRUCTION_BOILERPLATE()
     208         246 :   LoadObjectFieldInstruction(const ClassType* class_type,
     209             :                              std::string field_name)
     210         492 :       : class_type(class_type), field_name(std::move(field_name)) {}
     211             :   const ClassType* class_type;
     212             :   std::string field_name;
     213             : };
     214             : 
     215        5540 : struct StoreObjectFieldInstruction : InstructionBase {
     216             :   TORQUE_INSTRUCTION_BOILERPLATE()
     217         280 :   StoreObjectFieldInstruction(const ClassType* class_type,
     218             :                               std::string field_name)
     219         560 :       : class_type(class_type), field_name(std::move(field_name)) {}
     220             :   const ClassType* class_type;
     221             :   std::string field_name;
     222             : };
     223             : 
     224        2201 : struct CallIntrinsicInstruction : InstructionBase {
     225             :   TORQUE_INSTRUCTION_BOILERPLATE()
     226          92 :   CallIntrinsicInstruction(Intrinsic* intrinsic,
     227             :                            TypeVector specialization_types,
     228             :                            std::vector<std::string> constexpr_arguments)
     229             :       : intrinsic(intrinsic),
     230             :         specialization_types(std::move(specialization_types)),
     231         184 :         constexpr_arguments(constexpr_arguments) {}
     232             : 
     233             :   Intrinsic* intrinsic;
     234             :   TypeVector specialization_types;
     235             :   std::vector<std::string> constexpr_arguments;
     236             : };
     237             : 
     238       74868 : struct CallCsaMacroInstruction : InstructionBase {
     239             :   TORQUE_INSTRUCTION_BOILERPLATE()
     240             :   CallCsaMacroInstruction(Macro* macro,
     241             :                           std::vector<std::string> constexpr_arguments,
     242             :                           base::Optional<Block*> catch_block)
     243             :       : macro(macro),
     244             :         constexpr_arguments(constexpr_arguments),
     245        4670 :         catch_block(catch_block) {}
     246           0 :   void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
     247           0 :     if (catch_block) block_list->push_back(*catch_block);
     248           0 :   }
     249             : 
     250             :   Macro* macro;
     251             :   std::vector<std::string> constexpr_arguments;
     252             :   base::Optional<Block*> catch_block;
     253             : };
     254             : 
     255       13386 : struct CallCsaMacroAndBranchInstruction : InstructionBase {
     256             :   TORQUE_INSTRUCTION_BOILERPLATE()
     257         582 :   CallCsaMacroAndBranchInstruction(Macro* macro,
     258             :                                    std::vector<std::string> constexpr_arguments,
     259             :                                    base::Optional<Block*> return_continuation,
     260             :                                    std::vector<Block*> label_blocks,
     261             :                                    base::Optional<Block*> catch_block)
     262             :       : macro(macro),
     263             :         constexpr_arguments(constexpr_arguments),
     264             :         return_continuation(return_continuation),
     265             :         label_blocks(label_blocks),
     266         582 :         catch_block(catch_block) {}
     267         389 :   bool IsBlockTerminator() const override { return true; }
     268           0 :   void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
     269           0 :     if (catch_block) block_list->push_back(*catch_block);
     270           0 :     if (return_continuation) block_list->push_back(*return_continuation);
     271           0 :     for (Block* block : label_blocks) block_list->push_back(block);
     272           0 :   }
     273             : 
     274             :   Macro* macro;
     275             :   std::vector<std::string> constexpr_arguments;
     276             :   base::Optional<Block*> return_continuation;
     277             :   std::vector<Block*> label_blocks;
     278             :   base::Optional<Block*> catch_block;
     279             : };
     280             : 
     281        1848 : struct CallBuiltinInstruction : InstructionBase {
     282             :   TORQUE_INSTRUCTION_BOILERPLATE()
     283           9 :   bool IsBlockTerminator() const override { return is_tailcall; }
     284             :   CallBuiltinInstruction(bool is_tailcall, Builtin* builtin, size_t argc,
     285             :                          base::Optional<Block*> catch_block)
     286             :       : is_tailcall(is_tailcall),
     287             :         builtin(builtin),
     288             :         argc(argc),
     289         138 :         catch_block(catch_block) {}
     290           0 :   void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
     291           0 :     if (catch_block) block_list->push_back(*catch_block);
     292           0 :   }
     293             : 
     294             :   bool is_tailcall;
     295             :   Builtin* builtin;
     296             :   size_t argc;
     297             :   base::Optional<Block*> catch_block;
     298             : };
     299             : 
     300         319 : struct CallBuiltinPointerInstruction : InstructionBase {
     301             :   TORQUE_INSTRUCTION_BOILERPLATE()
     302           0 :   bool IsBlockTerminator() const override { return is_tailcall; }
     303             :   CallBuiltinPointerInstruction(bool is_tailcall,
     304             :                                 const BuiltinPointerType* type, size_t argc)
     305          23 :       : is_tailcall(is_tailcall), type(type), argc(argc) {}
     306             : 
     307             :   bool is_tailcall;
     308             :   const BuiltinPointerType* type;
     309             :   size_t argc;
     310             : };
     311             : 
     312         283 : struct CallRuntimeInstruction : InstructionBase {
     313             :   TORQUE_INSTRUCTION_BOILERPLATE()
     314             :   bool IsBlockTerminator() const override;
     315             : 
     316             :   CallRuntimeInstruction(bool is_tailcall, RuntimeFunction* runtime_function,
     317             :                          size_t argc, base::Optional<Block*> catch_block)
     318             :       : is_tailcall(is_tailcall),
     319             :         runtime_function(runtime_function),
     320             :         argc(argc),
     321          23 :         catch_block(catch_block) {}
     322           0 :   void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
     323           0 :     if (catch_block) block_list->push_back(*catch_block);
     324           0 :   }
     325             : 
     326             :   bool is_tailcall;
     327             :   RuntimeFunction* runtime_function;
     328             :   size_t argc;
     329             :   base::Optional<Block*> catch_block;
     330             : };
     331             : 
     332        8100 : struct BranchInstruction : InstructionBase {
     333             :   TORQUE_INSTRUCTION_BOILERPLATE()
     334          33 :   bool IsBlockTerminator() const override { return true; }
     335           0 :   void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
     336           0 :     block_list->push_back(if_true);
     337           0 :     block_list->push_back(if_false);
     338           0 :   }
     339             : 
     340             :   BranchInstruction(Block* if_true, Block* if_false)
     341         810 :       : if_true(if_true), if_false(if_false) {}
     342             : 
     343             :   Block* if_true;
     344             :   Block* if_false;
     345             : };
     346             : 
     347         848 : struct ConstexprBranchInstruction : InstructionBase {
     348             :   TORQUE_INSTRUCTION_BOILERPLATE()
     349           0 :   bool IsBlockTerminator() const override { return true; }
     350           0 :   void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
     351           0 :     block_list->push_back(if_true);
     352           0 :     block_list->push_back(if_false);
     353           0 :   }
     354             : 
     355          53 :   ConstexprBranchInstruction(std::string condition, Block* if_true,
     356             :                              Block* if_false)
     357         106 :       : condition(condition), if_true(if_true), if_false(if_false) {}
     358             : 
     359             :   std::string condition;
     360             :   Block* if_true;
     361             :   Block* if_false;
     362             : };
     363             : 
     364       43686 : struct GotoInstruction : InstructionBase {
     365             :   TORQUE_INSTRUCTION_BOILERPLATE()
     366        1998 :   bool IsBlockTerminator() const override { return true; }
     367           0 :   void AppendSuccessorBlocks(std::vector<Block*>* block_list) const override {
     368           0 :     block_list->push_back(destination);
     369           0 :   }
     370             : 
     371        5303 :   explicit GotoInstruction(Block* destination) : destination(destination) {}
     372             : 
     373             :   Block* destination;
     374             : };
     375             : 
     376        2660 : struct GotoExternalInstruction : InstructionBase {
     377             :   TORQUE_INSTRUCTION_BOILERPLATE()
     378          22 :   bool IsBlockTerminator() const override { return true; }
     379             : 
     380         133 :   GotoExternalInstruction(std::string destination,
     381             :                           std::vector<std::string> variable_names)
     382             :       : destination(std::move(destination)),
     383         266 :         variable_names(std::move(variable_names)) {}
     384             : 
     385             :   std::string destination;
     386             :   std::vector<std::string> variable_names;
     387             : };
     388             : 
     389        2808 : struct ReturnInstruction : InstructionBase {
     390             :   TORQUE_INSTRUCTION_BOILERPLATE()
     391         686 :   bool IsBlockTerminator() const override { return true; }
     392             : };
     393             : 
     394           0 : struct PrintConstantStringInstruction : InstructionBase {
     395             :   TORQUE_INSTRUCTION_BOILERPLATE()
     396           0 :   explicit PrintConstantStringInstruction(std::string message)
     397           0 :       : message(std::move(message)) {}
     398             : 
     399             :   std::string message;
     400             : };
     401             : 
     402        3510 : struct AbortInstruction : InstructionBase {
     403             :   TORQUE_INSTRUCTION_BOILERPLATE()
     404             :   enum class Kind { kDebugBreak, kUnreachable, kAssertionFailure };
     405         222 :   bool IsBlockTerminator() const override { return kind != Kind::kDebugBreak; }
     406         234 :   explicit AbortInstruction(Kind kind, std::string message = "")
     407         468 :       : kind(kind), message(std::move(message)) {}
     408             : 
     409             :   Kind kind;
     410             :   std::string message;
     411             : };
     412             : 
     413         649 : struct UnsafeCastInstruction : InstructionBase {
     414             :   TORQUE_INSTRUCTION_BOILERPLATE()
     415             :   explicit UnsafeCastInstruction(const Type* destination_type)
     416          40 :       : destination_type(destination_type) {}
     417             : 
     418             :   const Type* destination_type;
     419             : };
     420             : 
     421             : }  // namespace torque
     422             : }  // namespace internal
     423             : }  // namespace v8
     424             : 
     425             : #endif  // V8_TORQUE_INSTRUCTIONS_H_

Generated by: LCOV version 1.10