Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | List of all members
dart::kernel::PrologueBuilder Class Reference

#include <prologue_builder.h>

Inheritance diagram for dart::kernel::PrologueBuilder:
dart::kernel::BaseFlowGraphBuilder

Public Member Functions

 PrologueBuilder (const ParsedFunction *parsed_function, intptr_t last_used_id, bool compiling_for_osr, bool is_inlining)
 
BlockEntryInstrBuildPrologue (BlockEntryInstr *entry, PrologueInfo *prologue_info)
 
Fragment BuildParameterHandling ()
 
intptr_t last_used_block_id () const
 
- Public Member Functions inherited from dart::kernel::BaseFlowGraphBuilder
 BaseFlowGraphBuilder (const ParsedFunction *parsed_function, intptr_t last_used_block_id, intptr_t osr_id=DeoptId::kNone, ZoneGrowableArray< intptr_t > *context_level_array=nullptr, InlineExitCollector *exit_collector=nullptr, bool inlining_unchecked_entry=false)
 
const Arraycoverage_array () const
 
void FinalizeCoverageArray ()
 
Fragment LoadField (const Field &field, bool calls_initializer)
 
Fragment LoadNativeField (const Slot &native_field, InnerPointerAccess loads_inner_pointer, bool calls_initializer=false)
 
Fragment LoadNativeField (const Slot &native_field, bool calls_initializer=false)
 
Fragment LoadIndexed (classid_t class_id, intptr_t index_scale=compiler::target::kWordSize, bool index_unboxed=false, AlignmentType alignment=kAlignedAccess)
 
Fragment GenericCheckBound ()
 
Fragment LoadUntagged (intptr_t offset)
 
Fragment CalculateElementAddress (intptr_t index_scale)
 
Fragment ConvertUntaggedToUnboxed ()
 
Fragment ConvertUnboxedToUntagged ()
 
Fragment FloatToDouble ()
 
Fragment DoubleToFloat ()
 
void SetTempIndex (Definition *definition)
 
Fragment LoadLocal (LocalVariable *variable)
 
Fragment StoreLocal (LocalVariable *variable)
 
Fragment StoreLocal (TokenPosition position, LocalVariable *variable)
 
Fragment StoreLocalRaw (TokenPosition position, LocalVariable *variable)
 
Fragment LoadContextAt (int depth)
 
Fragment GuardFieldLength (const Field &field, intptr_t deopt_id)
 
Fragment GuardFieldClass (const Field &field, intptr_t deopt_id)
 
Fragment StoreNativeField (TokenPosition position, const Slot &slot, InnerPointerAccess stores_inner_pointer, StoreFieldInstr::Kind kind=StoreFieldInstr::Kind::kOther, StoreBarrierType emit_store_barrier=kEmitStoreBarrier, compiler::Assembler::MemoryOrder memory_order=compiler::Assembler::kRelaxedNonAtomic)
 
Fragment StoreNativeField (TokenPosition position, const Slot &slot, StoreFieldInstr::Kind kind=StoreFieldInstr::Kind::kOther, StoreBarrierType emit_store_barrier=kEmitStoreBarrier, compiler::Assembler::MemoryOrder memory_order=compiler::Assembler::kRelaxedNonAtomic)
 
Fragment StoreNativeField (const Slot &slot, InnerPointerAccess stores_inner_pointer, StoreFieldInstr::Kind kind=StoreFieldInstr::Kind::kOther, StoreBarrierType emit_store_barrier=kEmitStoreBarrier, compiler::Assembler::MemoryOrder memory_order=compiler::Assembler::kRelaxedNonAtomic)
 
Fragment StoreNativeField (const Slot &slot, StoreFieldInstr::Kind kind=StoreFieldInstr::Kind::kOther, StoreBarrierType emit_store_barrier=kEmitStoreBarrier, compiler::Assembler::MemoryOrder memory_order=compiler::Assembler::kRelaxedNonAtomic)
 
Fragment StoreField (const Field &field, StoreFieldInstr::Kind kind=StoreFieldInstr::Kind::kOther, StoreBarrierType emit_store_barrier=kEmitStoreBarrier)
 
Fragment StoreFieldGuarded (const Field &field, StoreFieldInstr::Kind kind=StoreFieldInstr::Kind::kOther)
 
Fragment LoadStaticField (const Field &field, bool calls_initializer)
 
Fragment RedefinitionWithType (const AbstractType &type)
 
Fragment ReachabilityFence ()
 
Fragment StoreStaticField (TokenPosition position, const Field &field)
 
Fragment StoreIndexed (classid_t class_id)
 
Fragment StoreIndexedTypedData (classid_t class_id, intptr_t index_scale, bool index_unboxed, AlignmentType alignment=kAlignedAccess)
 
Fragment Box (Representation from)
 
void Push (Definition *definition)
 
DefinitionPeek (intptr_t depth=0)
 
ValuePop ()
 
Fragment Drop ()
 
Fragment DropTempsPreserveTop (intptr_t num_temps_to_drop)
 
Fragment MakeTemp ()
 
LocalVariableMakeTemporary (const char *suffix=nullptr)
 
Fragment DropTemporary (LocalVariable **temp)
 
InputsArray GetArguments (int count)
 
TargetEntryInstrBuildTargetEntry ()
 
FunctionEntryInstrBuildFunctionEntry (GraphEntryInstr *graph_entry)
 
JoinEntryInstrBuildJoinEntry ()
 
JoinEntryInstrBuildJoinEntry (intptr_t try_index)
 
IndirectEntryInstrBuildIndirectEntry (intptr_t indirect_id, intptr_t try_index)
 
Fragment StrictCompare (TokenPosition position, Token::Kind kind, bool number_check=false)
 
Fragment StrictCompare (Token::Kind kind, bool number_check=false)
 
Fragment Goto (JoinEntryInstr *destination)
 
Fragment UnboxedIntConstant (int64_t value, Representation representation)
 
Fragment IntConstant (int64_t value)
 
Fragment Constant (const Object &value)
 
Fragment NullConstant ()
 
Fragment SmiRelationalOp (Token::Kind kind)
 
Fragment SmiBinaryOp (Token::Kind op, bool is_truncating=false)
 
Fragment BinaryIntegerOp (Token::Kind op, Representation representation, bool is_truncating=false)
 
Fragment LoadFpRelativeSlot (intptr_t offset, CompileType result_type, Representation representation=kTagged)
 
Fragment StoreFpRelativeSlot (intptr_t offset)
 
Fragment BranchIfTrue (TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry, bool negate=false)
 
Fragment BranchIfNull (TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry, bool negate=false)
 
Fragment BranchIfEqual (TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry, bool negate=false)
 
Fragment BranchIfStrictEqual (TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry)
 
Fragment Return (TokenPosition position)
 
Fragment CheckStackOverflow (TokenPosition position, intptr_t stack_depth, intptr_t loop_depth)
 
Fragment CheckStackOverflowInPrologue (TokenPosition position)
 
Fragment MemoryCopy (classid_t src_cid, classid_t dest_cid, bool unboxed_inputs, bool can_overlap=true)
 
Fragment TailCall (const Code &code)
 
Fragment Utf8Scan ()
 
intptr_t GetNextDeoptId ()
 
intptr_t AllocateTryIndex ()
 
intptr_t CurrentTryIndex () const
 
void SetCurrentTryIndex (intptr_t try_index)
 
bool IsCompiledForOsr ()
 
bool IsInlining () const
 
void InlineBailout (const char *reason)
 
Fragment LoadArgDescriptor ()
 
Fragment TestTypeArgsLen (Fragment eq_branch, Fragment neq_branch, intptr_t num_type_args)
 
Fragment TestDelayedTypeArgs (LocalVariable *closure, Fragment present, Fragment absent)
 
Fragment TestAnyTypeArgs (Fragment present, Fragment absent)
 
JoinEntryInstrBuildThrowNoSuchMethod ()
 
Fragment ThrowException (TokenPosition position)
 
Fragment AssertBool (TokenPosition position)
 
Fragment BooleanNegate ()
 
Fragment AllocateContext (const ZoneGrowableArray< const Slot * > &scope)
 
Fragment AllocateClosure (TokenPosition position, bool has_instantiator_type_args, bool is_generic, bool is_tear_off)
 
Fragment CreateArray ()
 
Fragment AllocateRecord (TokenPosition position, RecordShape shape)
 
Fragment AllocateSmallRecord (TokenPosition position, RecordShape shape)
 
Fragment AllocateTypedData (TokenPosition position, classid_t class_id)
 
Fragment InstantiateType (const AbstractType &type)
 
Fragment InstantiateTypeArguments (const TypeArguments &type_arguments)
 
Fragment InstantiateDynamicTypeArguments ()
 
Fragment LoadClassId ()
 
bool InliningUncheckedEntry () const
 
intptr_t GetStackDepth () const
 
Fragment AllocateObject (TokenPosition position, const Class &klass, intptr_t argument_count)
 
Fragment DebugStepCheck (TokenPosition position)
 
Fragment CheckNull (TokenPosition position, LocalVariable *receiver, const String &function_name)
 
Fragment CheckNullOptimized (const String &name, CheckNullInstr::ExceptionType exception_type, TokenPosition position=TokenPosition::kNoSource)
 
Fragment CheckNullOptimized (const String &function_name, TokenPosition position=TokenPosition::kNoSource)
 
Fragment CheckNotDeeplyImmutable (CheckWritableInstr::Kind kind)
 
void RecordUncheckedEntryPoint (GraphEntryInstr *graph_entry, FunctionEntryInstr *unchecked_entry)
 
Fragment BuildEntryPointsIntrospection ()
 
Fragment ClosureCall (const Function &target_function, TokenPosition position, intptr_t type_args_len, intptr_t argument_count, const Array &argument_names, const InferredTypeMetadata *result_type=nullptr)
 
Fragment AssertAssignable (TokenPosition position, const String &dst_name, AssertAssignableInstr::Kind kind=AssertAssignableInstr::kUnknown)
 
bool is_recording_context_levels () const
 
void set_context_depth (intptr_t context_level)
 
void reset_context_depth_for_deopt_id (intptr_t deopt_id)
 
Fragment InitConstantParameters ()
 
Fragment InvokeMathCFunction (MethodRecognizer::Kind recognized_kind, intptr_t num_inputs)
 
Fragment DoubleToInteger (MethodRecognizer::Kind recognized_kind)
 
Fragment UnaryDoubleOp (Token::Kind op)
 
Fragment RecordCoverage (TokenPosition position)
 
Fragment RecordBranchCoverage (TokenPosition position)
 
bool has_saved_args_desc_array ()
 
const Arraysaved_args_desc_array ()
 

Static Public Member Functions

static bool HasEmptyPrologue (const Function &function)
 
static bool PrologueSkippableOnUncheckedEntry (const Function &function)
 
- Static Public Member Functions inherited from dart::kernel::BaseFlowGraphBuilder
static const FieldMayCloneField (Zone *zone, const Field &field)
 

Additional Inherited Members

- Protected Member Functions inherited from dart::kernel::BaseFlowGraphBuilder
intptr_t AllocateBlockId ()
 
Fragment RecordCoverageImpl (TokenPosition position, bool is_branch_coverage)
 
intptr_t GetCoverageIndexFor (intptr_t encoded_position)
 
- Protected Attributes inherited from dart::kernel::BaseFlowGraphBuilder
const ParsedFunctionparsed_function_
 
const Functionfunction_
 
Threadthread_
 
Zonezone_
 
intptr_t osr_id_
 
ZoneGrowableArray< intptr_t > * context_level_array_
 
intptr_t context_depth_
 
intptr_t last_used_block_id_
 
intptr_t current_try_index_
 
intptr_t next_used_try_index_
 
Valuestack_
 
InlineExitCollectorexit_collector_
 
const bool inlining_unchecked_entry_
 
const Arraysaved_args_desc_array_
 
IntMap< intptr_t > coverage_state_index_for_position_
 
Arraycoverage_array_
 

Detailed Description

Definition at line 39 of file prologue_builder.h.

Constructor & Destructor Documentation

◆ PrologueBuilder()

dart::kernel::PrologueBuilder::PrologueBuilder ( const ParsedFunction parsed_function,
intptr_t  last_used_id,
bool  compiling_for_osr,
bool  is_inlining 
)
inline

Definition at line 41 of file prologue_builder.h.

45 : BaseFlowGraphBuilder(parsed_function, last_used_id),
46 compiling_for_osr_(compiling_for_osr),
47 is_inlining_(is_inlining) {}
BaseFlowGraphBuilder(const ParsedFunction *parsed_function, intptr_t last_used_block_id, intptr_t osr_id=DeoptId::kNone, ZoneGrowableArray< intptr_t > *context_level_array=nullptr, InlineExitCollector *exit_collector=nullptr, bool inlining_unchecked_entry=false)

Member Function Documentation

◆ BuildParameterHandling()

Fragment dart::kernel::PrologueBuilder::BuildParameterHandling ( )

Definition at line 96 of file prologue_builder.cc.

96 {
97 Fragment copy_args_prologue;
98 const int num_fixed_params = function_.num_fixed_parameters();
99 const int num_opt_pos_params = function_.NumOptionalPositionalParameters();
100 const int num_opt_named_params = function_.NumOptionalNamedParameters();
101 const int num_params =
102 num_fixed_params + num_opt_pos_params + num_opt_named_params;
103 ASSERT(function_.NumParameters() == num_params);
104
105 // This will contain information about registers assigned to fixed
106 // parameters as well as their stack locations relative to callee FP
107 // under the assumption that no other arguments were passed.
108 compiler::ParameterInfoArray fixed_params(num_fixed_params);
111 /*should_assign_stack_locations=*/true, &fixed_params);
112
113 // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args,
114 // where num_pos_args is the number of positional arguments passed in.
115 const int min_num_pos_args = num_fixed_params;
116
117 LocalVariable* count_var = nullptr;
118 LocalVariable* optional_count_var = nullptr;
119 if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
120 copy_args_prologue += LoadArgDescriptor();
121 copy_args_prologue +=
122 LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
123
124 copy_args_prologue += LoadArgDescriptor();
125 copy_args_prologue += LoadNativeField(Slot::ArgumentsDescriptor_count());
126 count_var = MakeTemporary();
127
128 copy_args_prologue += LoadLocal(count_var);
129 copy_args_prologue += IntConstant(min_num_pos_args);
130 copy_args_prologue += SmiBinaryOp(Token::kSUB, /* truncate= */ true);
131 optional_count_var = MakeTemporary();
132 }
133
134 // Copy mandatory parameters down.
135 intptr_t param = 0;
136 for (; param < num_fixed_params; ++param) {
137 const auto [location, representation] = fixed_params[param];
138
139 const auto lo_location =
140 location.IsPairLocation() ? location.AsPairLocation()->At(0) : location;
141
142 if (lo_location.IsMachineRegister()) {
143 continue;
144 }
145
146 if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
147 copy_args_prologue += LoadLocal(optional_count_var);
148 } else {
149 copy_args_prologue += IntConstant(0);
150 }
151 const intptr_t stack_slot_offset = lo_location.ToStackSlotOffset();
152 copy_args_prologue += LoadFpRelativeSlot(
153 stack_slot_offset,
154 ParameterType(ParameterVariable(param), representation),
155 representation);
156 copy_args_prologue +=
157 StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
158 copy_args_prologue += Drop();
159 }
160
161 // Copy optional parameters down.
162 if (num_opt_pos_params > 0) {
163 JoinEntryInstr* next_missing = nullptr;
164 for (intptr_t opt_param = 0; param < num_params; ++param, ++opt_param) {
165 TargetEntryInstr *supplied, *missing;
166 copy_args_prologue += IntConstant(opt_param + 1);
167 copy_args_prologue += LoadLocal(optional_count_var);
168 copy_args_prologue += SmiRelationalOp(Token::kLTE);
169 copy_args_prologue += BranchIfTrue(&supplied, &missing);
170
171 Fragment good(supplied);
172 good += LoadLocal(optional_count_var);
173 // Note: FP[param_end_from_fp + 1 + (optional_count_var - 1)] points to
174 // the first optional parameter.
175 good += LoadFpRelativeSlot(
177 (compiler::target::frame_layout.param_end_from_fp - opt_param),
178 ParameterType(ParameterVariable(param)));
179 good += StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
180 good += Drop();
181
182 Fragment not_good(missing);
183 if (next_missing != nullptr) {
184 not_good += Goto(next_missing);
185 not_good.current = next_missing;
186 }
187 next_missing = BuildJoinEntry();
188 not_good += Constant(DefaultParameterValueAt(opt_param));
189 not_good +=
190 StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
191 not_good += Drop();
192 not_good += Goto(next_missing);
193
194 copy_args_prologue.current = good.current;
195 }
196 copy_args_prologue += Goto(next_missing /* join good/not_good flows */);
197 copy_args_prologue.current = next_missing;
198
199 } else if (num_opt_named_params > 0) {
200 const intptr_t first_name_offset =
203
204 // Start by alphabetically sorting the names of the optional parameters.
205 int* opt_param_position = Z->Alloc<int>(num_opt_named_params);
206 SortOptionalNamedParametersInto(opt_param_position, num_fixed_params,
207 num_params);
208
209 LocalVariable* optional_count_vars_processed =
211 ASSERT(optional_count_vars_processed != nullptr);
212 copy_args_prologue += IntConstant(0);
213 copy_args_prologue +=
214 StoreLocalRaw(TokenPosition::kNoSource, optional_count_vars_processed);
215 copy_args_prologue += Drop();
216
217 for (intptr_t i = 0; param < num_params; ++param, ++i) {
218 copy_args_prologue += IntConstant(
221 copy_args_prologue += LoadLocal(optional_count_vars_processed);
222 copy_args_prologue += SmiBinaryOp(Token::kMUL, /* truncate= */ true);
223 LocalVariable* tuple_diff = MakeTemporary();
224
225 // Let's load position from arg descriptor (to see which parameter is the
226 // name) and move kEntrySize forward in ArgDescriptor names array.
227 //
228 // Later we'll either add this fragment directly to the copy_args_prologue
229 // if no check is needed or add an appropriate check.
230 Fragment good;
231 {
232 // fp[target::frame_layout.param_end_from_fp + (count_var - pos)]
233 good += LoadLocal(count_var);
234 {
235 // pos = arg_desc[names_offset + arg_desc_name_index + positionOffset]
236 good += LoadArgDescriptor();
237 good += IntConstant(
238 (first_name_offset +
241 good += LoadLocal(tuple_diff);
242 good += SmiBinaryOp(Token::kADD, /* truncate= */ true);
243 good += LoadIndexed(
244 kArrayCid, /*index_scale*/ compiler::target::kCompressedWordSize);
245 }
246 good += SmiBinaryOp(Token::kSUB, /* truncate= */ true);
247 good += LoadFpRelativeSlot(
249 compiler::target::frame_layout.param_end_from_fp,
250 ParameterType(ParameterVariable(opt_param_position[i])));
251
252 // Copy down.
253 good += StoreLocalRaw(TokenPosition::kNoSource,
254 ParameterVariable(opt_param_position[i]));
255 good += Drop();
256
257 // Increase processed optional variable count.
258 good += LoadLocal(optional_count_vars_processed);
259 good += IntConstant(1);
260 good += SmiBinaryOp(Token::kADD, /* truncate= */ true);
261 good += StoreLocalRaw(TokenPosition::kNoSource,
262 optional_count_vars_processed);
263 good += Drop();
264 }
265
266 const bool required = function_.IsRequiredAt(opt_param_position[i]);
267
268 if (required) {
269 copy_args_prologue += good;
270 } else {
271 // name = arg_desc[names_offset + arg_desc_name_index + nameOffset]
272 copy_args_prologue += LoadArgDescriptor();
273 copy_args_prologue +=
274 IntConstant((first_name_offset +
277 copy_args_prologue += LoadLocal(tuple_diff);
278 copy_args_prologue += SmiBinaryOp(Token::kADD, /* truncate= */ true);
279 copy_args_prologue += LoadIndexed(
280 kArrayCid, /*index_scale*/ compiler::target::kCompressedWordSize);
281
282 // first name in sorted list of all names
283 const String& param_name = String::ZoneHandle(
284 Z, function_.ParameterNameAt(opt_param_position[i]));
285 ASSERT(param_name.IsSymbol());
286 copy_args_prologue += Constant(param_name);
287
288 // Compare the two names: Note that the ArgumentDescriptor array always
289 // terminates with a "null" name (i.e. kNullCid), which will prevent us
290 // from running out-of-bounds.
291 TargetEntryInstr *supplied, *missing;
292 copy_args_prologue += BranchIfStrictEqual(&supplied, &missing);
293
294 // Join good/not_good.
295 JoinEntryInstr* join = BuildJoinEntry();
296
297 // Put good in the flowgraph as a separate basic block.
298 good.Prepend(supplied);
299 good += Goto(join);
300
301 // We had no match, so load the default constant.
302 Fragment not_good(missing);
303 not_good += Constant(
304 DefaultParameterValueAt(opt_param_position[i] - num_fixed_params));
305
306 // Copy down with default value.
307 not_good += StoreLocalRaw(TokenPosition::kNoSource,
308 ParameterVariable(opt_param_position[i]));
309 not_good += Drop();
310 not_good += Goto(join);
311
312 copy_args_prologue.current = join;
313 }
314
315 copy_args_prologue += Drop(); // tuple_diff
316 }
317 }
318
319 if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
320 copy_args_prologue += Drop(); // optional_count_var
321 copy_args_prologue += Drop(); // count_var
322 copy_args_prologue += Drop(); // positional_count_var
323 }
324
325 return copy_args_prologue;
326}
static intptr_t ComputeLocationsOfFixedParameters(Zone *zone, const Function &function, bool should_assign_stack_locations=false, compiler::ParameterInfoArray *parameter_info=nullptr)
Definition: flow_graph.cc:1204
StringPtr ParameterNameAt(intptr_t index) const
Definition: object.cc:8602
bool IsRequiredAt(intptr_t index) const
Definition: object.cc:8741
intptr_t NumOptionalNamedParameters() const
Definition: object.cc:8874
intptr_t NumOptionalPositionalParameters() const
Definition: object.cc:8871
intptr_t num_fixed_parameters() const
Definition: object.cc:8856
intptr_t NumParameters() const
Definition: object.cc:8877
static Object & ZoneHandle()
Definition: object.h:419
LocalVariable * expression_temp_var() const
Definition: parser.h:151
Fragment SmiRelationalOp(Token::Kind kind)
Fragment LoadLocal(LocalVariable *variable)
Fragment LoadFpRelativeSlot(intptr_t offset, CompileType result_type, Representation representation=kTagged)
Fragment StoreLocalRaw(TokenPosition position, LocalVariable *variable)
Fragment LoadNativeField(const Slot &native_field, InnerPointerAccess loads_inner_pointer, bool calls_initializer=false)
Fragment BranchIfTrue(TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry, bool negate=false)
Fragment LoadIndexed(classid_t class_id, intptr_t index_scale=compiler::target::kWordSize, bool index_unboxed=false, AlignmentType alignment=kAlignedAccess)
LocalVariable * MakeTemporary(const char *suffix=nullptr)
Fragment Constant(const Object &value)
Fragment SmiBinaryOp(Token::Kind op, bool is_truncating=false)
Fragment Goto(JoinEntryInstr *destination)
Fragment BranchIfStrictEqual(TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry)
#define ASSERT(E)
static constexpr intptr_t kWordSize
Definition: runtime_api.h:274
static constexpr intptr_t kCompressedWordSize
Definition: runtime_api.h:286
FrameLayout frame_layout
Definition: stack_frame.cc:76
GrowableArray< std::pair< Location, Representation > > ParameterInfoArray
static CompileType ParameterType(LocalVariable *param, Representation representation=kTagged)
#define Z
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741

◆ BuildPrologue()

BlockEntryInstr * dart::kernel::PrologueBuilder::BuildPrologue ( BlockEntryInstr entry,
PrologueInfo prologue_info 
)

Definition at line 47 of file prologue_builder.cc.

48 {
49 // We always have to build the graph, but we only link it sometimes.
50 const bool link = !is_inlining_ && !compiling_for_osr_;
51
52 const intptr_t previous_block_id = last_used_block_id_;
53
54 const bool copy_parameters = function_.MakesCopyOfParameters();
55 const bool expect_type_args = function_.IsGeneric();
56
57 Fragment prologue = Fragment(entry);
58
59 if (copy_parameters) {
60 Fragment f = BuildParameterHandling();
61 if (link) prologue += f;
62 }
64 Fragment f = BuildClosureContextHandling();
65 if (!compiling_for_osr_) prologue += f;
66 }
67 if (expect_type_args) {
68 Fragment f = BuildTypeArgumentsHandling();
69 if (link) prologue += f;
70
72 Fragment f = BuildClosureDelayedTypeArgumentsHandling();
73 if (!compiling_for_osr_) prologue += f;
74 }
75 }
76
77 const bool is_empty_prologue = prologue.entry == prologue.current;
78 // Double-check we create empty prologues when HasEmptyPrologue returns true.
79 ASSERT(!HasEmptyPrologue(function_) || is_empty_prologue);
80
81 // Always do this to preserve deoptid numbering.
82 JoinEntryInstr* normal_code = BuildJoinEntry();
83 Fragment jump_to_normal_code = Goto(normal_code);
84
85 if (is_empty_prologue) {
86 *prologue_info = PrologueInfo(-1, -1);
87 return entry;
88 } else {
89 prologue += jump_to_normal_code;
90 *prologue_info =
91 PrologueInfo(previous_block_id, normal_code->block_id() - 1);
92 return normal_code;
93 }
94}
bool MakesCopyOfParameters() const
Definition: object.h:3514
bool IsClosureFunction() const
Definition: object.h:3891
bool IsGeneric() const
Definition: object.cc:8844
static bool HasEmptyPrologue(const Function &function)
def link(from_root, to_root)
Definition: dart_pkg.py:44

◆ HasEmptyPrologue()

bool dart::kernel::PrologueBuilder::HasEmptyPrologue ( const Function function)
static

Definition at line 42 of file prologue_builder.cc.

42 {
43 return !function.MakesCopyOfParameters() && !function.IsGeneric() &&
44 !function.IsClosureFunction();
45}
Dart_NativeFunction function
Definition: fuchsia.cc:51

◆ last_used_block_id()

intptr_t dart::kernel::PrologueBuilder::last_used_block_id ( ) const
inline

Definition at line 57 of file prologue_builder.h.

57{ return last_used_block_id_; }

◆ PrologueSkippableOnUncheckedEntry()

bool dart::kernel::PrologueBuilder::PrologueSkippableOnUncheckedEntry ( const Function function)
static

Definition at line 36 of file prologue_builder.cc.

37 {
38 return !function.MakesCopyOfParameters() &&
39 !function.IsNonImplicitClosureFunction() && !function.IsGeneric();
40}

The documentation for this class was generated from the following files: