V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
turbo-assembler.h
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 
12 namespace v8 {
13 namespace internal {
14 
15 // Common base class for platform-specific TurboAssemblers containing
16 // platform-independent bits.
17 class V8_EXPORT_PRIVATE TurboAssemblerBase : public Assembler {
18  public:
19  Isolate* isolate() const {
20  DCHECK(!options().v8_agnostic_code);
21  return isolate_;
22  }
23 
24  Handle<HeapObject> CodeObject() const {
25  DCHECK(!code_object_.is_null());
26  return code_object_;
27  }
28 
29  bool root_array_available() const { return root_array_available_; }
30  void set_root_array_available(bool v) { root_array_available_ = v; }
31 
32  bool trap_on_abort() const { return trap_on_abort_; }
33 
34  bool should_abort_hard() const { return hard_abort_; }
35  void set_abort_hard(bool v) { hard_abort_ = v; }
36 
37  void set_builtin_index(int i) { maybe_builtin_index_ = i; }
38 
39  void set_has_frame(bool v) { has_frame_ = v; }
40  bool has_frame() const { return has_frame_; }
41 
42  // Loads the given constant or external reference without embedding its direct
43  // pointer. The produced code is isolate-independent.
44  void IndirectLoadConstant(Register destination, Handle<HeapObject> object);
45  void IndirectLoadExternalReference(Register destination,
46  ExternalReference reference);
47 
48  virtual void LoadFromConstantsTable(Register destination,
49  int constant_index) = 0;
50 
51  // Corresponds to: destination = kRootRegister + offset.
52  virtual void LoadRootRegisterOffset(Register destination,
53  intptr_t offset) = 0;
54 
55  // Corresponds to: destination = [kRootRegister + offset].
56  virtual void LoadRootRelative(Register destination, int32_t offset) = 0;
57 
58  virtual void LoadRoot(Register destination, RootIndex index) = 0;
59 
60  static int32_t RootRegisterOffsetForRootIndex(RootIndex root_index);
61  static int32_t RootRegisterOffsetForBuiltinIndex(int builtin_index);
62 
63  // Returns the root-relative offset to reference.address().
64  static intptr_t RootRegisterOffsetForExternalReference(
65  Isolate* isolate, const ExternalReference& reference);
66 
67  // Returns the root-relative offset to the external reference table entry,
68  // which itself contains reference.address().
69  static int32_t RootRegisterOffsetForExternalReferenceTableEntry(
70  Isolate* isolate, const ExternalReference& reference);
71 
72  // An address is addressable through kRootRegister if it is located within
73  // isolate->root_register_addressable_region().
74  static bool IsAddressableThroughRootRegister(
75  Isolate* isolate, const ExternalReference& reference);
76 
77  protected:
78  TurboAssemblerBase(const AssemblerOptions& options, void* buffer,
79  int buffer_size)
80  : TurboAssemblerBase(nullptr, options.EnableV8AgnosticCode(), buffer,
81  buffer_size, CodeObjectRequired::kNo) {}
82 
83  TurboAssemblerBase(Isolate* isolate, const AssemblerOptions& options,
84  void* buffer, int buffer_size,
85  CodeObjectRequired create_code_object);
86 
87  void RecordCommentForOffHeapTrampoline(int builtin_index);
88 
89  Isolate* const isolate_ = nullptr;
90 
91  // This handle will be patched with the code object on installation.
92  Handle<HeapObject> code_object_;
93 
94  // Whether kRootRegister has been initialized.
95  bool root_array_available_ = true;
96 
97  // Immediately trap instead of calling {Abort} when debug code fails.
98  bool trap_on_abort_ = FLAG_trap_on_abort;
99 
100  // Emit a C call to abort instead of a runtime call.
101  bool hard_abort_ = false;
102 
103  // May be set while generating builtins.
104  int maybe_builtin_index_ = Builtins::kNoBuiltinId;
105 
106  bool has_frame_ = false;
107 
108  DISALLOW_IMPLICIT_CONSTRUCTORS(TurboAssemblerBase);
109 };
110 
111 // Avoids emitting calls to the {Builtins::kAbort} builtin when emitting debug
112 // code during the lifetime of this scope object. For disabling debug code
113 // entirely use the {DontEmitDebugCodeScope} instead.
115  public:
116  explicit HardAbortScope(TurboAssemblerBase* assembler)
117  : assembler_(assembler), old_value_(assembler->should_abort_hard()) {
118  assembler_->set_abort_hard(true);
119  }
120  ~HardAbortScope() { assembler_->set_abort_hard(old_value_); }
121 
122  private:
123  TurboAssemblerBase* assembler_;
124  bool old_value_;
125 };
126 
127 // Helper stubs can be called in different ways depending on where the target
128 // code is located and how the call sequence is expected to look like:
129 // - JavaScript: Call on-heap {Code} object via {RelocInfo::CODE_TARGET}.
130 // - WebAssembly: Call native {WasmCode} stub via {RelocInfo::WASM_STUB_CALL}.
131 enum class StubCallMode { kCallOnHeapBuiltin, kCallWasmRuntimeStub };
132 
133 #ifdef DEBUG
134 template <typename RegType, typename... RegTypes,
135  // All arguments must be either Register or DoubleRegister.
136  typename = typename std::enable_if<
137  base::is_same<Register, RegType, RegTypes...>::value ||
138  base::is_same<DoubleRegister, RegType, RegTypes...>::value>::type>
139 inline bool AreAliased(RegType first_reg, RegTypes... regs) {
140  int num_different_regs = NumRegs(RegType::ListOf(first_reg, regs...));
141  int num_given_regs = sizeof...(regs) + 1;
142  return num_different_regs < num_given_regs;
143 }
144 #endif
145 
146 } // namespace internal
147 } // namespace v8
148 
149 #endif // V8_TURBO_ASSEMBLER_H_
Definition: libplatform.h:13