LCOV - code coverage report
Current view: top level - src - turbo-assembler.h (source / functions) Hit Total Coverage
Test: app.info Lines: 19 19 100.0 %
Date: 2019-02-19 Functions: 12 14 85.7 %

          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_TURBO_ASSEMBLER_H_
       6             : #define V8_TURBO_ASSEMBLER_H_
       7             : 
       8             : #include "src/assembler-arch.h"
       9             : #include "src/base/template-utils.h"
      10             : #include "src/builtins/builtins.h"
      11             : #include "src/roots.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : 
      16             : // Common base class for platform-specific TurboAssemblers containing
      17             : // platform-independent bits.
      18    35149582 : class V8_EXPORT_PRIVATE TurboAssemblerBase : public Assembler {
      19             :  public:
      20       23688 :   Isolate* isolate() const {
      21             :     DCHECK(!options().v8_agnostic_code);
      22       23688 :     return isolate_;
      23             :   }
      24             : 
      25      103656 :   Handle<HeapObject> CodeObject() const {
      26             :     DCHECK(!code_object_.is_null());
      27      103656 :     return code_object_;
      28             :   }
      29             : 
      30         168 :   bool root_array_available() const { return root_array_available_; }
      31     6865983 :   void set_root_array_available(bool v) { root_array_available_ = v; }
      32             : 
      33             :   bool trap_on_abort() const { return trap_on_abort_; }
      34             : 
      35          56 :   bool should_abort_hard() const { return hard_abort_; }
      36     1103082 :   void set_abort_hard(bool v) { hard_abort_ = v; }
      37             : 
      38     2160750 :   void set_builtin_index(int i) { maybe_builtin_index_ = i; }
      39             : 
      40     5559158 :   void set_has_frame(bool v) { has_frame_ = v; }
      41       86576 :   bool has_frame() const { return has_frame_; }
      42             : 
      43             :   // Calls the given builtin. If builtins are embedded, the trampoline Code
      44             :   // object on the heap is not used.
      45             :   virtual void CallBuiltinPointer(Register builtin_pointer) = 0;
      46             : 
      47             :   // Calls/jumps to the given Code object. If builtins are embedded, the
      48             :   // trampoline Code object on the heap is not used.
      49             :   virtual void CallCodeObject(Register code_object) = 0;
      50             :   virtual void JumpCodeObject(Register code_object) = 0;
      51             : 
      52             :   // Loads the given Code object's entry point into the destination register.
      53             :   virtual void LoadCodeObjectEntry(Register destination,
      54             :                                    Register code_object) = 0;
      55             : 
      56             :   // Loads the given constant or external reference without embedding its direct
      57             :   // pointer. The produced code is isolate-independent.
      58             :   void IndirectLoadConstant(Register destination, Handle<HeapObject> object);
      59             :   void IndirectLoadExternalReference(Register destination,
      60             :                                      ExternalReference reference);
      61             : 
      62             :   virtual void LoadFromConstantsTable(Register destination,
      63             :                                       int constant_index) = 0;
      64             : 
      65             :   // Corresponds to: destination = kRootRegister + offset.
      66             :   virtual void LoadRootRegisterOffset(Register destination,
      67             :                                       intptr_t offset) = 0;
      68             : 
      69             :   // Corresponds to: destination = [kRootRegister + offset].
      70             :   virtual void LoadRootRelative(Register destination, int32_t offset) = 0;
      71             : 
      72             :   virtual void LoadRoot(Register destination, RootIndex index) = 0;
      73             : 
      74             :   static int32_t RootRegisterOffsetForRootIndex(RootIndex root_index);
      75             :   static int32_t RootRegisterOffsetForBuiltinIndex(int builtin_index);
      76             : 
      77             :   // Returns the root-relative offset to reference.address().
      78             :   static intptr_t RootRegisterOffsetForExternalReference(
      79             :       Isolate* isolate, const ExternalReference& reference);
      80             : 
      81             :   // Returns the root-relative offset to the external reference table entry,
      82             :   // which itself contains reference.address().
      83             :   static int32_t RootRegisterOffsetForExternalReferenceTableEntry(
      84             :       Isolate* isolate, const ExternalReference& reference);
      85             : 
      86             :   // An address is addressable through kRootRegister if it is located within
      87             :   // isolate->root_register_addressable_region().
      88             :   static bool IsAddressableThroughRootRegister(
      89             :       Isolate* isolate, const ExternalReference& reference);
      90             : 
      91             :  protected:
      92             :   TurboAssemblerBase(const AssemblerOptions& options,
      93             :                      std::unique_ptr<AssemblerBuffer> buffer = {})
      94             :       : TurboAssemblerBase(nullptr, options.EnableV8AgnosticCode(),
      95             :                            CodeObjectRequired::kNo, std::move(buffer)) {}
      96             : 
      97      294822 :   TurboAssemblerBase(Isolate* isolate, CodeObjectRequired create_code_object,
      98             :                      std::unique_ptr<AssemblerBuffer> buffer = {})
      99             :       : TurboAssemblerBase(isolate, AssemblerOptions::Default(isolate),
     100      588139 :                            create_code_object, std::move(buffer)) {}
     101             : 
     102             :   TurboAssemblerBase(Isolate* isolate, const AssemblerOptions& options,
     103             :                      CodeObjectRequired create_code_object,
     104             :                      std::unique_ptr<AssemblerBuffer> buffer = {});
     105             : 
     106             :   void RecordCommentForOffHeapTrampoline(int builtin_index);
     107             : 
     108             :   Isolate* const isolate_ = nullptr;
     109             : 
     110             :   // This handle will be patched with the code object on installation.
     111             :   Handle<HeapObject> code_object_;
     112             : 
     113             :   // Whether kRootRegister has been initialized.
     114             :   bool root_array_available_ = true;
     115             : 
     116             :   // Immediately trap instead of calling {Abort} when debug code fails.
     117             :   bool trap_on_abort_ = FLAG_trap_on_abort;
     118             : 
     119             :   // Emit a C call to abort instead of a runtime call.
     120             :   bool hard_abort_ = false;
     121             : 
     122             :   // May be set while generating builtins.
     123             :   int maybe_builtin_index_ = Builtins::kNoBuiltinId;
     124             : 
     125             :   bool has_frame_ = false;
     126             : 
     127             :   DISALLOW_IMPLICIT_CONSTRUCTORS(TurboAssemblerBase);
     128             : };
     129             : 
     130             : // Avoids emitting calls to the {Builtins::kAbort} builtin when emitting debug
     131             : // code during the lifetime of this scope object. For disabling debug code
     132             : // entirely use the {DontEmitDebugCodeScope} instead.
     133             : class HardAbortScope {
     134             :  public:
     135          56 :   explicit HardAbortScope(TurboAssemblerBase* assembler)
     136          56 :       : assembler_(assembler), old_value_(assembler->should_abort_hard()) {
     137          56 :     assembler_->set_abort_hard(true);
     138          56 :   }
     139          56 :   ~HardAbortScope() { assembler_->set_abort_hard(old_value_); }
     140             : 
     141             :  private:
     142             :   TurboAssemblerBase* assembler_;
     143             :   bool old_value_;
     144             : };
     145             : 
     146             : #ifdef DEBUG
     147             : struct CountIfValidRegisterFunctor {
     148             :   template <typename RegType>
     149             :   constexpr int operator()(int count, RegType reg) const {
     150             :     return count + (reg.is_valid() ? 1 : 0);
     151             :   }
     152             : };
     153             : 
     154             : template <typename RegType, typename... RegTypes,
     155             :           // All arguments must be either Register or DoubleRegister.
     156             :           typename = typename std::enable_if<
     157             :               base::is_same<Register, RegType, RegTypes...>::value ||
     158             :               base::is_same<DoubleRegister, RegType, RegTypes...>::value>::type>
     159             : inline bool AreAliased(RegType first_reg, RegTypes... regs) {
     160             :   int num_different_regs = NumRegs(RegType::ListOf(first_reg, regs...));
     161             :   int num_given_regs =
     162             :       base::fold(CountIfValidRegisterFunctor{}, 0, first_reg, regs...);
     163             :   return num_different_regs < num_given_regs;
     164             : }
     165             : #endif
     166             : 
     167             : }  // namespace internal
     168             : }  // namespace v8
     169             : 
     170             : #endif  // V8_TURBO_ASSEMBLER_H_

Generated by: LCOV version 1.10