29 representation == kTagged,
31 : ((representation == kTagged)
38 return !
function.MakesCopyOfParameters() &&
50 const bool link = !is_inlining_ && !compiling_for_osr_;
59 if (copy_parameters) {
61 if (
link) prologue +=
f;
64 Fragment f = BuildClosureContextHandling();
65 if (!compiling_for_osr_) prologue +=
f;
67 if (expect_type_args) {
68 Fragment f = BuildTypeArgumentsHandling();
69 if (
link) prologue +=
f;
72 Fragment f = BuildClosureDelayedTypeArgumentsHandling();
73 if (!compiling_for_osr_) prologue +=
f;
77 const bool is_empty_prologue = prologue.
entry == prologue.
current;
85 if (is_empty_prologue) {
89 prologue += jump_to_normal_code;
101 const int num_params =
102 num_fixed_params + num_opt_pos_params + num_opt_named_params;
111 true, &fixed_params);
115 const int min_num_pos_args = num_fixed_params;
119 if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
121 copy_args_prologue +=
125 copy_args_prologue +=
LoadNativeField(Slot::ArgumentsDescriptor_count());
128 copy_args_prologue +=
LoadLocal(count_var);
129 copy_args_prologue +=
IntConstant(min_num_pos_args);
130 copy_args_prologue +=
SmiBinaryOp(Token::kSUB,
true);
136 for (; param < num_fixed_params; ++param) {
137 const auto [location, representation] = fixed_params[param];
139 const auto lo_location =
140 location.IsPairLocation() ? location.AsPairLocation()->
At(0) : location;
142 if (lo_location.IsMachineRegister()) {
146 if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
147 copy_args_prologue +=
LoadLocal(optional_count_var);
151 const intptr_t stack_slot_offset = lo_location.ToStackSlotOffset();
156 copy_args_prologue +=
157 StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
158 copy_args_prologue +=
Drop();
162 if (num_opt_pos_params > 0) {
164 for (intptr_t opt_param = 0; param < num_params; ++param, ++opt_param) {
167 copy_args_prologue +=
LoadLocal(optional_count_var);
169 copy_args_prologue +=
BranchIfTrue(&supplied, &missing);
179 good +=
StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
183 if (next_missing !=
nullptr) {
184 not_good +=
Goto(next_missing);
185 not_good.
current = next_missing;
188 not_good +=
Constant(DefaultParameterValueAt(opt_param));
190 StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
192 not_good +=
Goto(next_missing);
196 copy_args_prologue +=
Goto(next_missing );
197 copy_args_prologue.
current = next_missing;
199 }
else if (num_opt_named_params > 0) {
200 const intptr_t first_name_offset =
205 int* opt_param_position =
Z->Alloc<
int>(num_opt_named_params);
206 SortOptionalNamedParametersInto(opt_param_position, num_fixed_params,
211 ASSERT(optional_count_vars_processed !=
nullptr);
213 copy_args_prologue +=
214 StoreLocalRaw(TokenPosition::kNoSource, optional_count_vars_processed);
215 copy_args_prologue +=
Drop();
217 for (intptr_t
i = 0; param < num_params; ++param, ++
i) {
221 copy_args_prologue +=
LoadLocal(optional_count_vars_processed);
222 copy_args_prologue +=
SmiBinaryOp(Token::kMUL,
true);
254 ParameterVariable(opt_param_position[
i]));
258 good +=
LoadLocal(optional_count_vars_processed);
262 optional_count_vars_processed);
269 copy_args_prologue += good;
273 copy_args_prologue +=
277 copy_args_prologue +=
LoadLocal(tuple_diff);
278 copy_args_prologue +=
SmiBinaryOp(Token::kADD,
true);
286 copy_args_prologue +=
Constant(param_name);
304 DefaultParameterValueAt(opt_param_position[
i] - num_fixed_params));
308 ParameterVariable(opt_param_position[
i]));
315 copy_args_prologue +=
Drop();
319 if ((num_opt_pos_params > 0) || (num_opt_named_params > 0)) {
320 copy_args_prologue +=
Drop();
321 copy_args_prologue +=
Drop();
322 copy_args_prologue +=
Drop();
325 return copy_args_prologue;
328Fragment PrologueBuilder::BuildClosureContextHandling() {
335 populate_context +=
LoadLocal(closure_parameter);
337 populate_context +=
StoreLocal(TokenPosition::kNoSource, context);
338 populate_context +=
Drop();
339 return populate_context;
342Fragment PrologueBuilder::BuildTypeArgumentsHandling() {
344 ASSERT(type_args_var !=
nullptr);
348 Fragment store_type_args;
355 kTypeArgumentsCid,
nullptr));
356 store_type_args +=
StoreLocal(TokenPosition::kNoSource, type_args_var);
357 store_type_args +=
Drop();
361 store_null +=
StoreLocal(TokenPosition::kNoSource, type_args_var);
362 store_null +=
Drop();
369Fragment PrologueBuilder::BuildClosureDelayedTypeArgumentsHandling() {
372 LocalVariable*
const type_args_var =
374 ASSERT(type_args_var !=
nullptr);
381 Fragment use_delayed_type_args;
383 use_delayed_type_args +=
385 use_delayed_type_args +=
StoreLocal(TokenPosition::kNoSource, type_args_var);
386 use_delayed_type_args +=
Drop();
389 use_delayed_type_args,
393void PrologueBuilder::SortOptionalNamedParametersInto(
int* opt_param_position,
394 int num_fixed_params,
398 for (
int pos = num_fixed_params;
pos < num_params;
pos++) {
400 int i =
pos - num_fixed_params;
403 const intptr_t
result =
name.CompareTo(name_i);
406 opt_param_position[
i + 1] = opt_param_position[
i];
408 opt_param_position[
i + 1] =
pos;
const T & At(intptr_t index) const
intptr_t block_id() const
CompileType CopyNonNullable()
static constexpr bool kCannotBeSentinel
static constexpr bool kCanBeNull
static CompileType Dynamic()
static CompileType FromAbstractType(const AbstractType &type, bool can_be_null, bool can_be_sentinel)
static intptr_t ComputeLocationsOfFixedParameters(Zone *zone, const Function &function, bool should_assign_stack_locations=false, compiler::ParameterInfoArray *parameter_info=nullptr)
StringPtr ParameterNameAt(intptr_t index) const
bool IsRequiredAt(intptr_t index) const
bool MakesCopyOfParameters() const
bool IsClosureFunction() const
intptr_t NumOptionalNamedParameters() const
intptr_t NumOptionalPositionalParameters() const
intptr_t num_fixed_parameters() const
intptr_t NumParameters() const
const AbstractType & static_type() const
bool was_type_checked_by_caller() const
static Object & ZoneHandle()
LocalVariable * expression_temp_var() const
const Function & function() const
LocalVariable * RawTypeArgumentsVariable() const
LocalVariable * ParameterVariable(intptr_t i) const
LocalVariable * current_context_var() const
static word position_offset()
static word name_offset()
static word named_entry_size()
static word first_named_entry_offset()
static word data_offset()
Fragment IntConstant(int64_t value)
Fragment SmiRelationalOp(Token::Kind kind)
Fragment TestDelayedTypeArgs(LocalVariable *closure, Fragment present, Fragment absent)
Fragment LoadLocal(LocalVariable *variable)
intptr_t last_used_block_id_
Fragment LoadFpRelativeSlot(intptr_t offset, CompileType result_type, Representation representation=kTagged)
Fragment LoadArgDescriptor()
JoinEntryInstr * BuildJoinEntry()
Fragment StoreLocalRaw(TokenPosition position, LocalVariable *variable)
Fragment StoreLocal(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 TestTypeArgsLen(Fragment eq_branch, Fragment neq_branch, intptr_t num_type_args)
const Function & function_
Fragment Constant(const Object &value)
const ParsedFunction * parsed_function_
Fragment SmiBinaryOp(Token::Kind op, bool is_truncating=false)
Fragment Goto(JoinEntryInstr *destination)
Fragment BranchIfStrictEqual(TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry)
void Prepend(Instruction *start)
BlockEntryInstr * BuildPrologue(BlockEntryInstr *entry, PrologueInfo *prologue_info)
Fragment BuildParameterHandling()
static bool HasEmptyPrologue(const Function &function)
static bool PrologueSkippableOnUncheckedEntry(const Function &function)
Dart_NativeFunction function
static constexpr intptr_t kWordSize
static constexpr intptr_t kCompressedWordSize
static CompileType ParameterType(LocalVariable *param, Representation representation=kTagged)
def link(from_root, to_root)
std::function< void()> closure
static SkString join(const CommandLineFlags::StringArray &)