22#define IG (thread_->isolate_group())
35 if (
entry ==
nullptr) {
38 }
else if (other.
entry !=
nullptr) {
52 if (
entry ==
nullptr) {
54 }
else if (
current !=
nullptr) {
63 if (
entry ==
nullptr) {
101 for (
auto branch : branches) {
102 *branch =
builder->BuildTargetEntry();
103 (*branch)->Goto(
join);
112 if (branches.
length() == 1) {
139 while (
delta-- > 0) {
147 bool number_check ) {
158 bool number_check ) {
171 return instructions +
BranchIfEqual(then_entry, otherwise_entry, negate);
178 return instructions +
BranchIfEqual(then_entry, otherwise_entry, negate);
221 instructions <<= return_instr;
223 return instructions.
closed();
227 intptr_t stack_depth,
228 intptr_t loop_depth) {
281 dest_start,
length, unboxed_inputs, can_overlap);
311 intptr_t num_type_args) {
317 return descriptor.
TypeArgsLen() == num_type_args ? eq_branch : neq_branch;
352 present.
Prepend(present_entry);
372 Goto(present_entry), 0);
384 intptr_t index_scale,
417 auto converted =
new (
Z)
426 auto converted =
new (
Z)
459 bool calls_initializer) {
465 const Slot& native_field,
467 bool calls_initializer) {
476 bool calls_initializer) {
483 return LoadNativeField(native_field, loads_inner_pointer, calls_initializer);
508 const Field& field) {
538 kind, emit_store_barrier);
546 if (
IG->use_field_guards()) {
553 instructions +=
LoadLocal(store_expression);
563 length_guard +=
LoadLocal(store_expression);
567 instructions += length_guard;
573 instructions +=
LoadLocal(store_expression);
584 bool calls_initializer) {
613 const Field& scan_flags_field =
623 const Field& field) {
637 index,
value, emit_store_barrier,
false,
644 intptr_t index_scale,
654 Instruction::SpeculativeMode::kNotSpeculative);
684 static constexpr intptr_t kTemporaryNameLength = 64;
685 char name[kTemporaryNameLength];
692 const String& symbol_name =
695 new (
Z)
LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
696 symbol_name, Object::dynamic_type());
707 item->definition()->set_ssa_temp_index(0);
714 ASSERT(temp !=
nullptr && *temp !=
nullptr && (*temp)->
HasIndex());
735 for (intptr_t
i = 0;
i < depth; ++
i) {
740 return head->definition();
749 value->set_next_use(
nullptr);
750 value->set_previous_use(
nullptr);
751 value->definition()->ClearSSATempIndex();
761 if (definition->
HasSSATemp() || definition->IsLoadLocal()) {
772 intptr_t num_temps_to_drop) {
775 for (intptr_t
i = 0;
i < num_temps_to_drop; ++
i) {
813 intptr_t indirect_id,
814 intptr_t try_index) {
822 for (intptr_t
i =
count - 1;
i >= 0; --
i) {
823 arguments[
i] =
Pop();
838 bool is_truncating) {
844 bool is_truncating) {
845 ASSERT(representation == kUnboxedInt32 || representation == kUnboxedUint32 ||
846 representation == kUnboxedInt64 || representation == kTagged);
882 Z,
IG->object_store()->call_closure_no_such_method_stub());
925 bool has_instantiator_type_args,
928 Value* instantiator_type_args =
929 (has_instantiator_type_args ?
Pop() :
nullptr);
930 auto const context =
Pop();
959 const intptr_t num_fields = shape.
num_fields();
960 ASSERT(num_fields == 2 || num_fields == 3);
961 Value* value2 = (num_fields > 2) ?
Pop() :
nullptr;
982 Value* instantiator_type_args =
Pop();
993 instructions +=
Constant(type_arguments_value);
997 Value* instantiator_type_args =
Pop();
1004 return instructions;
1010 Value* instantiator_type_args =
Pop();
1039 if (from == kUnboxedFloat) {
1041 from = kUnboxedDouble;
1044 instructions <<= box;
1046 return instructions;
1070 instructions <<= check_null;
1072 return instructions;
1090 auto* check_writable =
new (
Z)
1115 if (!FLAG_enable_testing_pragmas)
return Drop();
1119 if (
function.IsImplicitClosureFunction()) {
1130 Symbols::vm_trace_entrypoints(),
false,
1152 call_hook +=
LoadLocal(entry_point_num);
1153 if (FLAG_precompiled_mode) {
1158 call_hook +=
ClosureCall(Function::null_function(), TokenPosition::kNoSource,
1161 call_hook +=
Drop();
1169 intptr_t type_args_len,
1171 const Array& argument_names,
1174 const intptr_t total_count =
1179 target_function, std::move(arguments), type_args_len, argument_names,
1182 instructions <<=
call;
1183 if (result_type !=
nullptr && result_type->
IsConstant()) {
1184 instructions +=
Drop();
1187 return instructions;
1207 Value* instantiator_type_args =
Pop();
1222 for (intptr_t
i = 0;
i < parameter_count; ++
i) {
1225 if (param_value !=
nullptr) {
1226 instructions +=
Constant(*param_value);
1227 instructions +=
StoreLocalRaw(TokenPosition::kNoSource, raw_parameter);
1228 instructions +=
Drop();
1231 return instructions;
1236 intptr_t num_inputs) {
1271 bool is_branch_coverage) {
1274 if (!
IG->coverage())
return instructions;
1275 if (!position.
IsReal())
return instructions;
1276 if (is_branch_coverage && !
IG->branch_coverage())
return instructions;
1278 const intptr_t coverage_index =
1282 return instructions;
1341 for (
auto*
p = it.Next();
p !=
nullptr;
p = it.Next()) {
1345 const intptr_t coverage_entry_index =
p->value - 1;
static float next(float f)
#define DEBUG_ASSERT(cond)
#define ASSERT_EQUAL(expected, actual)
intptr_t TypeArgsLen() const
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
ObjectPtr At(intptr_t index) const
void SetAt(intptr_t index, const Object &value) const
Iterator GetIterator() const
const T & At(intptr_t index) const
void SetLength(intptr_t new_length)
static BinaryIntegerOpInstr * Make(Representation representation, Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
static const Bool & True()
static BoxInstr * Create(Representation from, Value *value)
TargetEntryInstr ** false_successor_address()
TargetEntryInstr ** true_successor_address()
static constexpr bool kCannotBeSentinel
static constexpr bool kCanBeNull
static CompileType FromAbstractType(const AbstractType &type, bool can_be_null, bool can_be_sentinel)
static CompilerState & Current()
void set_temp_index(intptr_t index)
intptr_t temp_index() const
static constexpr intptr_t kNone
FieldPtr CloneFromOriginal() const
bool needs_length_check() const
StaticTypeExactnessState static_type_exactness_state() const
static Representation ReturnRepresentationOf(const Function &function)
static intptr_t ComputeArgumentsSizeInWords(const Function &function, intptr_t arguments_count)
bool IsImplicitClosureFunction() const
bool IsClosureFunction() const
intptr_t NumParameters() const
void set_unchecked_entry(FunctionEntryInstr *target)
void set_normal_entry(FunctionEntryInstr *entry)
void AddExit(DartReturnInstr *exit)
void LinkTo(Instruction *next)
V Lookup(const Key &key) const
void Insert(const Key &key, const Value &value)
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
static IntegerPtr NewCanonical(const String &str)
static bool FindPragma(Thread *T, bool only_core, const Object &object, const String &pragma_name, bool multiple=false, Object *options=nullptr)
int context_level() const
LocalScope * owner() const
void set_index(VariableIndex index)
const Object * inferred_arg_value() const
static Object & ZoneHandle()
void Bailout(const char *origin, const char *reason) const
const Function & function() const
int num_stack_locals() const
LocalVariable * arg_desc_var() const
bool has_arg_desc_var() const
LocalVariable * ParameterVariable(intptr_t i) const
LocalVariable * current_context_var() const
LocalVariable * RawParameterVariable(intptr_t i) const
intptr_t num_fields() const
void set_constrained_type(CompileType *type)
static FunctionPtr ResolveFunction(Zone *zone, const Class &receiver_class, const String &function_name)
static const Slot & GetContextVariableSlotFor(Thread *thread, const LocalVariable &var)
static const Slot & Get(const Field &field, const ParsedFunction *parsed_function)
Representation representation() const
bool may_contain_inner_pointer() const
static SmiPtr New(intptr_t value)
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
static StringPtr Concat(const String &str1, const String &str2, Heap::Space space=Heap::kNew)
static StringPtr New(Thread *thread, const char *cstr)
intptr_t EncodeCoveragePosition(bool is_branch_coverage)
static int SNPrint(char *str, size_t size, const char *format,...) PRINTF_ATTRIBUTE(3
void set_previous_use(Value *previous)
static void AddToList(Value *value, Value **list)
Definition * definition() const
static word ElementSizeFor(intptr_t cid)
Fragment IntConstant(int64_t value)
IntMap< intptr_t > coverage_state_index_for_position_
Fragment SmiRelationalOp(Token::Kind kind)
Fragment TestDelayedTypeArgs(LocalVariable *closure, Fragment present, Fragment absent)
Fragment LoadLocal(LocalVariable *variable)
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 ThrowException(TokenPosition position)
Fragment RecordCoverageImpl(TokenPosition position, bool is_branch_coverage)
Fragment GenericCheckBound()
Definition * Peek(intptr_t depth=0)
void SetTempIndex(Definition *definition)
Fragment InitConstantParameters()
Fragment TestAnyTypeArgs(Fragment present, Fragment absent)
const Array & saved_args_desc_array_
Fragment ConvertUnboxedToUntagged()
Fragment LoadContextAt(int depth)
Fragment DebugStepCheck(TokenPosition position)
const Array & saved_args_desc_array()
ZoneGrowableArray< intptr_t > * context_level_array_
Fragment CalculateElementAddress(intptr_t index_scale)
JoinEntryInstr * BuildThrowNoSuchMethod()
InputsArray GetArguments(int count)
Fragment LoadFpRelativeSlot(intptr_t offset, CompileType result_type, Representation representation=kTagged)
Fragment InvokeMathCFunction(MethodRecognizer::Kind recognized_kind, intptr_t num_inputs)
Fragment LoadArgDescriptor()
void reset_context_depth_for_deopt_id(intptr_t deopt_id)
Fragment StoreField(const Field &field, StoreFieldInstr::Kind kind=StoreFieldInstr::Kind::kOther, StoreBarrierType emit_store_barrier=kEmitStoreBarrier)
JoinEntryInstr * BuildJoinEntry()
Fragment GuardFieldLength(const Field &field, intptr_t deopt_id)
Fragment CheckNotDeeplyImmutable(CheckWritableInstr::Kind kind)
Fragment StoreLocalRaw(TokenPosition position, LocalVariable *variable)
Fragment AllocateTypedData(TokenPosition position, classid_t class_id)
Fragment AllocateRecord(TokenPosition position, RecordShape shape)
Fragment StoreFpRelativeSlot(intptr_t offset)
Fragment MemoryCopy(classid_t src_cid, classid_t dest_cid, bool unboxed_inputs, bool can_overlap=true)
bool is_recording_context_levels() const
Fragment InstantiateTypeArguments(const TypeArguments &type_arguments)
Fragment CheckNull(TokenPosition position, LocalVariable *receiver, const String &function_name)
intptr_t AllocateBlockId()
Fragment StoreStaticField(TokenPosition position, const Field &field)
void InlineBailout(const char *reason)
Fragment AllocateSmallRecord(TokenPosition position, RecordShape shape)
Fragment InstantiateType(const AbstractType &type)
Fragment StoreIndexedTypedData(classid_t class_id, intptr_t index_scale, bool index_unboxed, AlignmentType alignment=kAlignedAccess)
void FinalizeCoverageArray()
Fragment LoadUntagged(intptr_t offset)
Fragment RecordBranchCoverage(TokenPosition position)
Fragment TailCall(const Code &code)
Fragment AssertBool(TokenPosition position)
Fragment InstantiateDynamicTypeArguments()
Fragment BuildEntryPointsIntrospection()
Fragment AssertAssignable(TokenPosition position, const String &dst_name, AssertAssignableInstr::Kind kind=AssertAssignableInstr::kUnknown)
Fragment StoreLocal(LocalVariable *variable)
Fragment LoadField(const Field &field, bool calls_initializer)
Fragment DropTempsPreserveTop(intptr_t num_temps_to_drop)
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)
FunctionEntryInstr * BuildFunctionEntry(GraphEntryInstr *graph_entry)
Fragment GuardFieldClass(const Field &field, intptr_t deopt_id)
Fragment LoadNativeField(const Slot &native_field, InnerPointerAccess loads_inner_pointer, bool calls_initializer=false)
Fragment StoreFieldGuarded(const Field &field, StoreFieldInstr::Kind kind=StoreFieldInstr::Kind::kOther)
InlineExitCollector * exit_collector_
Fragment LoadStaticField(const Field &field, bool calls_initializer)
Fragment BranchIfTrue(TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry, bool negate=false)
intptr_t GetCoverageIndexFor(intptr_t encoded_position)
Fragment BranchIfEqual(TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry, bool negate=false)
Fragment UnboxedIntConstant(int64_t value, Representation representation)
Fragment RedefinitionWithType(const AbstractType &type)
Fragment LoadIndexed(classid_t class_id, intptr_t index_scale=compiler::target::kWordSize, bool index_unboxed=false, AlignmentType alignment=kAlignedAccess)
Fragment RecordCoverage(TokenPosition position)
Fragment Return(TokenPosition position)
bool InliningUncheckedEntry() const
TargetEntryInstr * BuildTargetEntry()
bool has_saved_args_desc_array()
Fragment Box(Representation from)
IndirectEntryInstr * BuildIndirectEntry(intptr_t indirect_id, intptr_t try_index)
intptr_t GetStackDepth() const
void RecordUncheckedEntryPoint(GraphEntryInstr *graph_entry, FunctionEntryInstr *unchecked_entry)
LocalVariable * MakeTemporary(const char *suffix=nullptr)
static const Field & MayCloneField(Zone *zone, const Field &field)
Fragment BinaryIntegerOp(Token::Kind op, Representation representation, bool is_truncating=false)
Fragment CheckStackOverflow(TokenPosition position, intptr_t stack_depth, intptr_t loop_depth)
Fragment TestTypeArgsLen(Fragment eq_branch, Fragment neq_branch, intptr_t num_type_args)
intptr_t GetNextDeoptId()
Fragment AllocateClosure(TokenPosition position, bool has_instantiator_type_args, bool is_generic, bool is_tear_off)
Fragment UnaryDoubleOp(Token::Kind op)
const Function & function_
const Array & coverage_array() const
Fragment StrictCompare(TokenPosition position, Token::Kind kind, bool number_check=false)
Fragment AllocateObject(TokenPosition position, const Class &klass, intptr_t argument_count)
Fragment Constant(const Object &value)
Fragment StoreIndexed(classid_t class_id)
const ParsedFunction * parsed_function_
Fragment CheckNullOptimized(const String &name, CheckNullInstr::ExceptionType exception_type, TokenPosition position=TokenPosition::kNoSource)
void Push(Definition *definition)
Fragment SmiBinaryOp(Token::Kind op, bool is_truncating=false)
intptr_t CurrentTryIndex() const
Fragment DoubleToInteger(MethodRecognizer::Kind recognized_kind)
Fragment BranchIfNull(TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry, bool negate=false)
Fragment ConvertUntaggedToUnboxed()
Fragment DropTemporary(LocalVariable **temp)
Fragment CheckStackOverflowInPrologue(TokenPosition position)
Fragment ReachabilityFence()
Fragment Goto(JoinEntryInstr *destination)
Fragment AllocateContext(const ZoneGrowableArray< const Slot * > &scope)
Fragment BranchIfStrictEqual(TargetEntryInstr **then_entry, TargetEntryInstr **otherwise_entry)
void Prepend(Instruction *start)
Fragment & operator<<=(Instruction *next)
Fragment & operator+=(const Fragment &other)
BlockEntryInstr * CreateSuccessorFor(BaseFlowGraphBuilder *builder, const TestFragment::SuccessorAddressArray &branches)
SuccessorAddressArray * true_successor_addresses
SuccessorAddressArray * false_successor_addresses
BlockEntryInstr * CreateTrueSuccessor(BaseFlowGraphBuilder *builder)
BlockEntryInstr * CreateFalseSuccessor(BaseFlowGraphBuilder *builder)
void ConnectBranchesTo(BaseFlowGraphBuilder *builder, const TestFragment::SuccessorAddressArray &branches, JoinEntryInstr *join)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Dart_NativeFunction function
const Field & LookupConvertUtf8DecoderScanFlagsField()
Fragment operator+(const Fragment &first, const Fragment &second)
static bool SupportsCoverage()
Fragment operator<<(const Fragment &fragment, Instruction *next)
bool IsTypedDataBaseClassId(intptr_t index)
static constexpr Representation kUnboxedAddress
const char *const function_name
std::function< void()> closure
int compare(const void *untyped_lhs, const void *untyped_rhs)
static SkString join(const CommandLineFlags::StringArray &)