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

Generated by: LCOV version 1.10