Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
stub_code_compiler.h
Go to the documentation of this file.
1// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_COMPILER_STUB_CODE_COMPILER_H_
6#define RUNTIME_VM_COMPILER_STUB_CODE_COMPILER_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
12#include <functional>
13
14#include "vm/allocation.h"
16#include "vm/constants.h"
17#include "vm/growable_array.h"
18#include "vm/stub_code_list.h"
19#include "vm/tagged_pointer.h"
20
21namespace dart {
22
23// Forward declarations.
24class Code;
25class DescriptorList;
26class Label;
27
28namespace compiler {
29
30// Forward declarations.
31class Assembler;
32
33// Represents an unresolved PC-relative Call/TailCall.
35 public:
37 const dart::Code& target,
38 bool is_tail_call)
39 : offset_(offset), target_(target), is_tail_call_(is_tail_call) {}
40
41 intptr_t offset() const { return offset_; }
42 const dart::Code& target() const { return target_; }
43 bool is_tail_call() const { return is_tail_call_; }
44
45 private:
46 const intptr_t offset_;
47 const dart::Code& target_;
48 const bool is_tail_call_;
49};
50
52
54 public:
55 StubCodeCompiler(Assembler* assembler_, DescriptorList* pc_descriptors_list)
56 : assembler(assembler_), pc_descriptors_list_(pc_descriptors_list) {}
57
59
61 static ArrayPtr BuildStaticCallsTable(
62 Zone* zone,
63 compiler::UnresolvedPcRelativeCalls* unresolved_calls);
64
65#define STUB_CODE_GENERATE(name) void Generate##name##Stub();
67#undef STUB_CODE_GENERATE
68
70 UnresolvedPcRelativeCalls* unresolved_calls,
71 const Class& cls,
72 const dart::Code& allocate_object,
73 const dart::Code& allocat_object_parametrized);
74
87 void GenerateNArgsCheckInlineCacheStub(intptr_t num_args,
88 const RuntimeEntry& handle_ic_miss,
89 Token::Kind kind,
90 Optimized optimized,
92 Exactness exactness);
94 intptr_t num_args,
95 const RuntimeEntry& handle_ic_miss,
96 Token::Kind kind,
97 Optimized optimized,
99 Exactness exactness,
100 CodeEntryKind entry_kind);
103
104 // Calculates the offset (in words) from FP to the provided [cpu_register].
105 //
106 // Assumes
107 // * all [kDartAvailableCpuRegs] followed by saved-PC, saved-FP were
108 // pushed on the stack
109 // * [cpu_register] is in [kDartAvailableCpuRegs]
110 //
111 // The intended use of this function is to find registers on the stack which
112 // were spilled in the
113 // `StubCode::*<stub-name>Shared{With,Without}FpuRegsStub()`
114 static intptr_t WordOffsetFromFpToCpuRegister(Register cpu_register);
115
116#if !defined(TARGET_ARCH_IA32)
117 // Used for passing functions that generate exit branches for a
118 // SubtypeTestCache search stub. Must generate a return instruction.
119 using STCSearchExitGenerator = std::function<void(Assembler*, int)>;
120#endif
121
122 private:
123#if !defined(TARGET_ARCH_IA32)
124 // Generates the code for searching a subtype test cache for an entry that
125 // matches the contents of the TypeTestABI registers. If no matching
126 // entry is found, then the code generated by [not_found] is executed.
127 // Otherwise, the code generated by [found] is executed, which can assume
128 // that [cache_entry_reg] points to the start of the matching cache entry.
129 // Both generators should return from the stub and not fall through.
130 //
131 // Inputs in addition to those in TypeTestABI:
132 // - null_reg: a register containing the address Object::null().
133 //
134 // The following registers from TypeTestABI are inputs under the following
135 // conditions:
136 // - kScratchReg: always
137 // - kInstanceReg: always
138 // - kDstTypeReg: [n] >= 3
139 // - kInstantiatorTypeArgumentsReg: [n] >= 4
140 // - kFunctionTypeArgumentsReg: [n] >= 5
141 //
142 // Has the following input registers in addition to those in TypeTestABI:
143 // - null_reg: contains the ObjectPtr for Object::null()
144 // - cache_entry_reg: contains the ArrayPtr for the backing array of the STC
145 //
146 // The following registers must be provided for the given conditions and
147 // are clobbered, and can be kNoRegister otherwise:
148 // - instance_cid_or_sig_reg: always
149 // - instance_type_args_reg: [n] >= 2
150 // - parent_fun_type_args_reg: [n] >= 6
151 // - delayed_type_args_reg: [n] >= 7
152 //
153 // The following registers must be distinct from other inputs when provided,
154 // but can be kNoRegister:
155 // - cache_entry_end_reg: used in the hash-based cache iteration loop
156 // on each iteration
157 // - cache_entry_start_reg, used in the hash-based cache iteration loop
158 // to reset if iteration hits the end of the entries
159 // - cache_entry_count_reg, used to calculate the starting index to probe
160 // Note that if any of these are kNoRegister, then a stack slot is used to
161 // store and retrieve the corresponding value.
162 //
163 // Note that all input registers must be distinct, except for the case
164 // of kInstanceReg, which can be used for one of [delayed_type_args_reg],
165 // [cache_entry_end_reg], [cache_entry_start_reg], or [cache_entry_count_reg],
166 // which are all set after the last use of kInstanceReg.
167 //
168 // Also note that if any non-TypeTestABI registers overlap with any
169 // non-scratch TypeTestABI registers, the original value of the TypeTestABI
170 // register must be stored before the generated code and restored afterwards.
171 static void GenerateSubtypeTestCacheSearch(
173 int n,
174 Register null_reg,
175 Register cache_entry_reg,
176 Register instance_cid_or_sig_reg,
177 Register instance_type_args_reg,
178 Register parent_fun_type_args_reg,
179 Register delayed_type_args_reg,
180 Register cache_entry_end_reg,
181 Register cache_entry_start_reg,
182 Register cache_entry_count_reg,
183 const STCSearchExitGenerator& gen_found,
184 const STCSearchExitGenerator& gen_not_found);
185#endif
186
187 // Common function for generating the different SubtypeTestCache search
188 // stubs. Check architecture-specific version for inputs/outputs.
189 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n);
190
191 // Common function for generating InitLateStaticField and
192 // InitLateFinalStaticField stubs.
193 void GenerateInitLateStaticFieldStub(bool is_final);
194
195 // Common function for generating InitLateInstanceField and
196 // InitLateFinalInstanceField stubs.
197 void GenerateInitLateInstanceFieldStub(bool is_final);
198
199 // Common function for generating AllocateClosure[TA][Generic] stubs.
200 void GenerateAllocateClosureStub(bool has_instantiator_type_args,
201 bool is_generic);
202
203 // Common function for generating Allocate<TypedData>Array stubs.
204 void GenerateAllocateTypedDataArrayStub(intptr_t cid);
205
206 void GenerateAllocateSmallRecordStub(intptr_t num_fields,
207 bool has_named_fields);
208
209 void GenerateSharedStubGeneric(bool save_fpu_registers,
210 intptr_t self_code_stub_offset_from_thread,
211 bool allow_return,
212 std::function<void()> perform_runtime_call);
213
214 // Generates shared slow path stub which saves registers and calls
215 // [target] runtime entry.
216 // If [store_runtime_result_in_result_register], then stub puts result into
217 // SharedSlowPathStubABI::kResultReg.
218 void GenerateSharedStub(bool save_fpu_registers,
219 const RuntimeEntry* target,
220 intptr_t self_code_stub_offset_from_thread,
221 bool allow_return,
222 bool store_runtime_result_in_result_register = false);
223
224 void GenerateLateInitializationError(bool with_fpu_regs);
225
226 void GenerateRangeError(bool with_fpu_regs);
227 void GenerateWriteError(bool with_fpu_regs);
228
229 void GenerateSuspendStub(bool call_suspend_function,
230 bool pass_type_arguments,
231 intptr_t suspend_entry_point_offset_in_thread,
232 intptr_t suspend_function_offset_in_object_store);
233 void GenerateInitSuspendableFunctionStub(
234 intptr_t init_entry_point_offset_in_thread,
235 intptr_t init_function_offset_in_object_store);
236 void GenerateReturnStub(intptr_t return_entry_point_offset_in_thread,
237 intptr_t return_function_offset_in_object_store,
238 intptr_t return_stub_offset_in_thread);
239
240 void GenerateLoadBSSEntry(BSS::Relocation relocation,
241 Register dst,
242 Register tmp);
243 void InsertBSSRelocation(BSS::Relocation reloc);
244
245 void GenerateLoadFfiCallbackMetadataRuntimeFunction(uword function_index,
246 Register dst);
247
248 DescriptorList* pc_descriptors_list_ = nullptr;
249
251};
252
253} // namespace compiler
254
256
257// Zap value used to indicate unused CODE_REG in deopt.
258static constexpr uword kZapCodeReg = 0xf1f1f1f1;
259
260// Zap value used to indicate unused return address in deopt.
261static constexpr uword kZapReturnAddress = 0xe1e1e1e1;
262
263} // namespace dart
264
265#endif // RUNTIME_VM_COMPILER_STUB_CODE_COMPILER_H_
void GenerateNArgsCheckInlineCacheStub(intptr_t num_args, const RuntimeEntry &handle_ic_miss, Token::Kind kind, Optimized optimized, CallType type, Exactness exactness)
static ArrayPtr BuildStaticCallsTable(Zone *zone, compiler::UnresolvedPcRelativeCalls *unresolved_calls)
Definition stub_code.cc:147
std::function< void(Assembler *, int)> STCSearchExitGenerator
void GenerateUsageCounterIncrement(Register temp_reg)
void GenerateAllocationStubForClass(UnresolvedPcRelativeCalls *unresolved_calls, const Class &cls, const dart::Code &allocate_object, const dart::Code &allocat_object_parametrized)
void GenerateNArgsCheckInlineCacheStubForEntryKind(intptr_t num_args, const RuntimeEntry &handle_ic_miss, Token::Kind kind, Optimized optimized, CallType type, Exactness exactness, CodeEntryKind entry_kind)
static intptr_t WordOffsetFromFpToCpuRegister(Register cpu_register)
StubCodeCompiler(Assembler *assembler_, DescriptorList *pc_descriptors_list)
UnresolvedPcRelativeCall(intptr_t offset, const dart::Code &target, bool is_tail_call)
static constexpr uword kZapReturnAddress
uintptr_t uword
Definition globals.h:501
const intptr_t cid
static constexpr uword kZapCodeReg
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
#define STUB_CODE_GENERATE(name)
#define VM_STUB_CODE_LIST(V)