5#ifndef RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_COMPILER_H_
6#define RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_COMPILER_H_
9#if defined(DART_PRECOMPILED_RUNTIME)
10#error "AOT runtime should not use compiler sources (including header files)"
27class CatchEntryMovesMapBuilder;
29class DeoptInfoBuilder;
31class FlowGraphCompiler;
36class SpeculativeInliningPolicy;
87 const Array& deopt_table);
95 intptr_t
deopt_id()
const {
return deopt_id_; }
97 uint32_t
flags()
const {
return flags_; }
106 const intptr_t deopt_id_;
108 const uint32_t flags_;
130 const char* kFormat =
"Deopt stub for id %d, reason: %s";
149 : instruction_(
instruction), entry_label_(), exit_label_() {}
222 virtual const char*
name() = 0;
233 bool save_fpu_registers) {
251 return instruction()->AsCheckNull()->exception_type();
254 const char*
name()
override;
257 bool save_fpu_registers)
override;
266 bool save_fpu_registers);
279 ? kRangeErrorUnboxedInt64RuntimeEntry
280 : kRangeErrorRuntimeEntry) {}
281 virtual const char*
name() {
return "check bound"; }
293 bool save_fpu_registers);
300 virtual const char*
name() {
return "check writable"; }
303 bool save_fpu_registers);
316 kLateFieldNotInitializedErrorRuntimeEntry) {
319 virtual const char*
name() {
return "late initialization error"; }
328 bool save_fpu_registers);
331 FieldPtr OriginalField()
const {
333 ?
instruction()->AsLoadField()->slot().field().Original()
334 :
instruction()->AsLoadStaticField()->field().Original();
344 jump_label_(&block_label_),
345 next_nonempty_label_(
nullptr),
357 return next_nonempty_label_;
360 next_nonempty_label_ = label;
363 bool WasCompacted()
const {
return jump_label_ != &block_label_; }
367 bool is_marked()
const {
return is_marked_; }
368 void mark() { is_marked_ =
true; }
408 return dispatch_table_call_targets_;
451 ASSERT(intrinsic_slow_path_label_ ==
nullptr || label ==
nullptr);
452 intrinsic_slow_path_label_ = label;
455 ASSERT(intrinsic_slow_path_label_ !=
nullptr);
456 return intrinsic_slow_path_label_;
464 if (stats_ !=
nullptr) stats_->
Begin(instr);
468 if (stats_ !=
nullptr) stats_->
End(instr);
476 if (stats_ !=
nullptr) stats_->
SpecialEnd(tag);
480 return used_static_fields_;
496 void Bailout(
const char* reason);
552#if !defined(TARGET_ARCH_IA32)
567 intptr_t sub_type_cache_index);
619 bool receiver_can_be_smi);
645 const Class& type_class,
664 bool fall_through_if_inside =
false);
688 intptr_t total_call_count,
689 bool receiver_can_be_smi =
true);
696 const Array& arguments_descriptor =
703 const Array& arguments_descriptor,
714 bool receiver_can_be_smi =
true);
725 intptr_t total_ic_calls,
729 const Array& arguments_descriptor);
733 bool needs_number_check,
738 bool needs_number_check,
773 intptr_t yield_index);
786#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
825 intptr_t slow_path_argument_count = 0);
862 intptr_t num_slow_path_args) {
864 if (pending_deoptimization_env_ ==
nullptr) {
876 intptr_t num_slow_path_args);
879 if (current_block_ ==
nullptr) {
892 const String& target_name,
893 const Array& arguments_descriptor,
894 intptr_t num_args_tested,
900 const Array& arguments_descriptor,
901 intptr_t num_args_tested,
907 const Array& args_desc_array);
910 return *deopt_id_to_ic_data_;
931 bool* class_is_abstract_return =
nullptr);
941 bool jump_on_miss =
true);
947 const Array& arguments_descriptor,
948 intptr_t size_with_type_args,
972 void EmitFrameEntry();
974 bool TryIntrinsifyHelper();
977 void AddPcRelativeCallStubTarget(
const Code& stub_code);
978 void AddPcRelativeTailCallStubTarget(
const Code& stub_code);
983 void GenerateDeferredCode();
991 void EmitUnoptimizedStaticCall(
992 intptr_t size_with_type_args,
1001 intptr_t ComputeGoodBiasForCidComparison(
const CallTargets& sorted,
1002 intptr_t max_immediate);
1006 static Register EmitTestCidRegister();
1008 void EmitTestAndCallLoadReceiver(intptr_t count_without_type_args,
1009 const Array& arguments_descriptor);
1011 void EmitTestAndCallSmiBranch(
compiler::Label* label,
bool jump_if_smi);
1013 void EmitTestAndCallLoadCid(
Register class_id_reg);
1016 void CheckClassIds(
Register class_id_reg,
1021 SubtypeTestCachePtr GenerateInlineInstanceof(
1027 SubtypeTestCachePtr GenerateInstantiatedTypeWithArgumentsTest(
1033 bool GenerateInstantiatedTypeNoArgumentsTest(
1039 SubtypeTestCachePtr GenerateUninstantiatedTypeTest(
1045 SubtypeTestCachePtr GenerateFunctionTypeTest(
1051 SubtypeTestCachePtr GenerateSubtype1TestCacheLookup(
1053 const Class& type_class,
1057 enum class TypeTestStubKind {
1059 kTestTypeOneArg = 1,
1061 kTestTypeTwoArgs = 2,
1063 kTestTypeThreeArgs = 3,
1065 kTestTypeFourArgs = 4,
1067 kTestTypeSixArgs = 6,
1069 kTestTypeSevenArgs = 7,
1072 static_assert(
static_cast<intptr_t
>(TypeTestStubKind::kTestTypeSevenArgs) ==
1074 "Need to adjust kTestTypeMaxArgs");
1075 static constexpr TypeTestStubKind kTestTypeMaxArgs =
1076 TypeTestStubKind::kTestTypeSevenArgs;
1079 intptr_t UsedInputsForTTSKind(TypeTestStubKind kind) {
1080 return static_cast<intptr_t
>(kind);
1084 TypeTestStubKind GetTypeTestStubKindForTypeParameter(
1085 const TypeParameter& type_param);
1089 SubtypeTestCachePtr GenerateCallSubtypeTestStub(
1090 TypeTestStubKind test_kind,
1091 compiler::Label* is_instance_lbl,
1092 compiler::Label* is_not_instance_lbl);
1094 void GenerateBoolToJump(
Register bool_reg,
1095 compiler::Label* is_true,
1096 compiler::Label* is_false);
1099 void AllocateRegistersLocally(Instruction* instr);
1104 intptr_t reverse_index(intptr_t index)
const {
1105 return block_order_.length() - index - 1;
1112 void CompactBlock(BlockEntryInstr* block);
1113 void CompactBlocks();
1115 bool IsListClass(
const Class& cls)
const {
1116 return cls.ptr() == list_class_.
ptr();
1119 void EmitSourceLine(Instruction* instr);
1121 intptr_t GetOptimizationThreshold()
const;
1124 void FrameStateUpdateWith(Instruction* instr);
1125 void FrameStatePush(Definition* defn);
1126 void FrameStatePop(intptr_t
count);
1127 bool FrameStateIsSafeToCall();
1128 void FrameStateClear();
1133 bool IsPeephole(Instruction* instr)
const;
1136 bool CanCallDart()
const {
1137 return current_instruction_ ==
nullptr ||
1141 bool CanCallDart()
const {
return true; }
1144 bool CanPcRelativeCall(
const Function&
target)
const;
1145 bool CanPcRelativeCall(
const Code&
target)
const;
1146 bool CanPcRelativeCall(
const AbstractType&
target)
const;
1149 class StaticCallsStruct :
public ZoneAllocated {
1156 const AbstractType* dst_type;
1159 intptr_t offset_arg,
1160 const Function* function_arg,
1161 const Code* code_arg,
1162 const AbstractType* dst_type)
1163 : call_kind(call_kind),
1164 entry_point(entry_point),
1168 dst_type(dst_type) {
1170 function->IsNotTemporaryScopedHandle());
1173 dst_type->IsNotTemporaryScopedHandle());
1174 ASSERT(code ==
nullptr || dst_type ==
nullptr);
1183 compiler::Assembler* assembler_;
1184 const ParsedFunction& parsed_function_;
1185 const FlowGraph& flow_graph_;
1186 const FlowGraph* intrinsic_flow_graph_ =
nullptr;
1187 const GrowableArray<BlockEntryInstr*>& block_order_;
1190 GrowableArray<Representation> frame_state_;
1196 BlockEntryInstr* current_block_;
1197 ExceptionHandlerList* exception_handlers_list_;
1198 DescriptorList* pc_descriptors_list_;
1199 CompressedStackMapsBuilder* compressed_stackmaps_builder_;
1200 CodeSourceMapBuilder* code_source_map_builder_;
1201 CatchEntryMovesMapBuilder* catch_entry_moves_maps_builder_;
1202 GrowableArray<BlockInfo*> block_info_;
1203 GrowableArray<CompilerDeoptInfo*> deopt_infos_;
1204 GrowableArray<SlowPathCode*> slow_path_code_;
1207 GrowableArray<const Field*> used_static_fields_;
1211 GrowableArray<StaticCallsStruct*> static_calls_target_table_;
1213 GrowableArray<const compiler::TableSelector*> dispatch_table_call_targets_;
1214 GrowableArray<IndirectGotoInstr*> indirect_gotos_;
1215 bool is_optimizing_;
1216 SpeculativeInliningPolicy* speculative_policy_;
1218 bool may_reoptimize_;
1220 bool intrinsic_mode_;
1221 compiler::Label* intrinsic_slow_path_label_ =
nullptr;
1222 bool fully_intrinsified_ =
false;
1223 CodeStatistics* stats_;
1228 Definition* top_of_stack_ =
nullptr;
1230 const Class& double_class_;
1231 const Class& mint_class_;
1232 const Class& float32x4_class_;
1233 const Class& float64x2_class_;
1234 const Class& int32x4_class_;
1235 const Class& list_class_;
1241 Environment* pending_deoptimization_env_;
1243 ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data_;
1244 Array& edge_counters_array_;
1247 Instruction* current_instruction_ =
nullptr;
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define DEBUG_ASSERT(cond)
intptr_t try_index() const
static void Allocate(FlowGraphCompiler *compiler, Instruction *instruction, const Class &cls, Register result, Register temp)
virtual void EmitNativeCode(FlowGraphCompiler *compiler)
BoxAllocationSlowPath(Instruction *instruction, const Class &cls, Register result)
StringPtr target_name() const
ArrayPtr arguments_descriptor() const
static void AddMetadataForRuntimeCall(CheckNullInstr *check_null, FlowGraphCompiler *compiler)
void End(Instruction *instruction)
void SpecialBegin(intptr_t tag)
void SpecialEnd(intptr_t tag)
void Begin(Instruction *instruction)
CompilerDeoptInfoWithStub(intptr_t deopt_id, ICData::DeoptReasonId reason, uint32_t flags, Environment *deopt_env)
const char * Name() const
compiler::Label * entry_label()
virtual void GenerateCode(FlowGraphCompiler *compiler, intptr_t stub_ix)
intptr_t deopt_id() const
virtual void GenerateCode(FlowGraphCompiler *compiler, intptr_t stub_ix)
intptr_t pc_offset() const
const Environment * deopt_env() const
ICData::DeoptReasonId reason() const
void set_pc_offset(intptr_t offset)
TypedDataPtr CreateDeoptInfo(FlowGraphCompiler *compiler, DeoptInfoBuilder *builder, const Array &deopt_table)
CompilerDeoptInfo(intptr_t deopt_id, ICData::DeoptReasonId reason, uint32_t flags, Environment *deopt_env)
virtual ~CompilerDeoptInfo()
ConstantTemporaryAllocator(Register tmp)
Register AllocateTemporary() override
void ReleaseTemporary() override
virtual void EmitNativeCode(FlowGraphCompiler *compiler)
DoubleToIntegerSlowPath(DoubleToIntegerInstr *instruction, FpuRegister value_reg)
IsolateGroup * isolate_group() const
void EmitDropArguments(intptr_t count)
static bool GenerateCidRangesCheck(compiler::Assembler *assembler, Register class_id_reg, const CidRangeVector &cid_ranges, compiler::Label *inside_range_lbl, compiler::Label *outside_range_lbl=nullptr, bool fall_through_if_inside=false)
Condition EmitEqualityRegConstCompare(Register reg, const Object &obj, bool needs_number_check, const InstructionSource &source, intptr_t deopt_id)
void EmitTailCallToStub(const Code &stub)
void EmitMegamorphicInstanceCall(const String &function_name, const Array &arguments_descriptor, intptr_t deopt_id, const InstructionSource &source, LocationSummary *locs)
void AddStubCallTarget(const Code &code)
Instruction * current_instruction() const
void EmitJumpToStub(const Code &stub)
void StatsBegin(Instruction *instr)
bool skip_body_compilation() const
void RecordSafepoint(LocationSummary *locs, intptr_t slow_path_argument_count=0)
void EmitOptimizedStaticCall(const Function &function, const Array &arguments_descriptor, intptr_t size_with_type_args, intptr_t deopt_id, const InstructionSource &source, LocationSummary *locs, Code::EntryKind entry_kind=Code::EntryKind::kNormal)
void EmitCallToStub(const Code &stub, ObjectPool::SnapshotBehavior snapshot_behavior=compiler::ObjectPoolBuilderEntry::kSnapshotable)
bool CheckAssertAssignableTypeTestingABILocations(const LocationSummary &locs)
void FinalizeVarDescriptors(const Code &code)
void set_current_block(BlockEntryInstr *value)
BranchLabels CreateBranchLabels(BranchInstr *branch) const
const Function & function() const
void GenerateStaticDartCall(intptr_t deopt_id, const InstructionSource &source, UntaggedPcDescriptors::Kind kind, LocationSummary *locs, const Function &target, Code::EntryKind entry_kind=Code::EntryKind::kNormal)
bool is_optimizing() const
intptr_t CurrentTryIndex() const
const Class & float64x2_class() const
const Class & BoxClassFor(Representation rep)
Condition EmitBoolTest(Register value, BranchLabels labels, bool invert)
void InsertBSSRelocation(BSS::Relocation reloc)
void AddExceptionHandler(CatchBlockEntryInstr *entry)
void SaveLiveRegisters(LocationSummary *locs)
bool ForcedOptimization() const
ArrayPtr edge_counters_array() const
CompilerDeoptInfo * AddDeoptIndexAtCall(intptr_t deopt_id, Environment *env)
const Class & double_class() const
void FinalizeCatchEntryMovesMap(const Code &code)
bool ForceSlowPathForStackOverflow() const
void GenerateNumberTypeCheck(Register kClassIdReg, const AbstractType &type, compiler::Label *is_instance_lbl, compiler::Label *is_not_instance_lbl)
const FlowGraph & flow_graph() const
compiler::Label * GetJumpLabel(BlockEntryInstr *block_entry) const
void RecordCatchEntryMoves(Environment *env)
void set_intrinsic_flow_graph(const FlowGraph &flow_graph)
intptr_t StackSize() const
const ParsedFunction & parsed_function() const
intptr_t ExtraStackSlotsOnOsrEntry() const
friend class CheckStackOverflowSlowPath
static bool LookupMethodFor(int class_id, const String &name, const ArgumentsDescriptor &args_desc, Function *fn_return, bool *class_is_abstract_return=nullptr)
bool WasCompacted(BlockEntryInstr *block_entry) const
void AddDescriptor(UntaggedPcDescriptors::Kind kind, intptr_t pc_offset, intptr_t deopt_id, const InstructionSource &source, intptr_t try_index, intptr_t yield_index=UntaggedPcDescriptors::kInvalidYieldIndex)
void EmitPolymorphicInstanceCall(const PolymorphicInstanceCallInstr *call, const CallTargets &targets, ArgumentsInfo args_info, intptr_t deopt_id, const InstructionSource &source, LocationSummary *locs, bool complete, intptr_t total_call_count, bool receiver_can_be_smi=true)
void EnterIntrinsicMode()
BlockEntryInstr * current_block() const
static constexpr intptr_t kMaxNumberOfCidRangesToTest
void EmitEdgeCounter(intptr_t edge_id)
compiler::Label * AddDeoptStub(intptr_t deopt_id, ICData::DeoptReasonId reason, uint32_t flags=0)
void EmitMoveToNative(const compiler::ffi::NativeLocation &dst, Location src_loc, Representation src_type, TemporaryRegisterAllocator *temp)
const Class & float32x4_class() const
void GenerateDartCall(intptr_t deopt_id, const InstructionSource &source, const Code &stub, UntaggedPcDescriptors::Kind kind, LocationSummary *locs, Code::EntryKind entry_kind=Code::EntryKind::kNormal)
bool CanFallThroughTo(BlockEntryInstr *block_entry) const
void EmitComment(Instruction *instr)
void EmitTestAndCall(const CallTargets &targets, const String &function_name, ArgumentsInfo args_info, compiler::Label *failed, compiler::Label *match_found, intptr_t deopt_id, const InstructionSource &source_index, LocationSummary *locs, bool complete, intptr_t total_ic_calls, Code::EntryKind entry_kind=Code::EntryKind::kNormal)
static const CallTargets * ResolveCallTargetsForReceiverCid(intptr_t cid, const String &selector, const Array &args_desc_array)
static int EmitTestAndCallCheckCid(compiler::Assembler *assembler, compiler::Label *label, Register class_id_reg, const CidRangeValue &range, int bias, bool jump_on_miss=true)
void SetNeedsStackTrace(intptr_t try_index)
CompilerDeoptInfo * AddSlowPathDeoptInfo(intptr_t deopt_id, Environment *env)
void RestoreLiveRegisters(LocationSummary *locs)
void EmitInstanceCallJIT(const Code &stub, const ICData &ic_data, intptr_t deopt_id, const InstructionSource &source, LocationSummary *locs, Code::EntryKind entry_kind)
const Class & mint_class() const
const ICData * GetOrAddInstanceCallICData(intptr_t deopt_id, const String &target_name, const Array &arguments_descriptor, intptr_t num_args_tested, const AbstractType &receiver_type, const Function &binary_smi_target)
void EmitMoveFromNative(Location dst_loc, Representation dst_type, const compiler::ffi::NativeLocation &src, TemporaryRegisterAllocator *temp)
bool IsEmptyBlock(BlockEntryInstr *block) const
void AddSlowPathCode(SlowPathCode *slow_path)
static bool SupportsUnboxedDoubles()
const GrowableArray< const compiler::TableSelector * > & dispatch_table_call_targets() const
static void GenerateIndirectTTSCall(compiler::Assembler *assembler, Register reg_with_type, intptr_t sub_type_cache_index)
void FinalizeStaticCallTargetsTable(const Code &code)
bool GenerateSubtypeRangeCheck(Register class_id_reg, const Class &type_class, compiler::Label *is_subtype_lbl)
void AddDispatchTableCallTarget(const compiler::TableSelector *selector)
void GenerateInstanceCall(intptr_t deopt_id, const InstructionSource &source, LocationSummary *locs, const ICData &ic_data, Code::EntryKind entry_kind, bool receiver_can_be_smi)
void EmitFunctionEntrySourcePositionDescriptorIfNeeded()
void LoadBSSEntry(BSS::Relocation relocation, Register dst, Register tmp)
void FinalizeExceptionHandlers(const Code &code)
void GenerateListTypeCheck(Register kClassIdReg, compiler::Label *is_instance_lbl)
void EmitDispatchTableCall(int32_t selector_offset, const Array &arguments_descriptor)
void GenerateTTSCall(const InstructionSource &source, intptr_t deopt_id, Environment *env, Register reg_with_type, const AbstractType &dst_type, const String &dst_name, LocationSummary *locs)
Condition EmitEqualityRegRegCompare(Register left, Register right, bool needs_number_check, const InstructionSource &source, intptr_t deopt_id)
void FinalizeStackMaps(const Code &code)
const Class & int32x4_class() const
const GrowableArray< BlockEntryInstr * > & block_order() const
bool may_reoptimize() const
bool CanOSRFunction() const
void GeneratePatchableCall(const InstructionSource &source, const Code &stub, UntaggedPcDescriptors::Kind kind, LocationSummary *locs, ObjectPool::SnapshotBehavior snapshot_behavior=compiler::ObjectPoolBuilderEntry::kSnapshotable)
void EmitMegamorphicInstanceCall(const ICData &icdata, intptr_t deopt_id, const InstructionSource &source, LocationSummary *locs)
void EmitOptimizedInstanceCall(const Code &stub, const ICData &ic_data, intptr_t deopt_id, const InstructionSource &source, LocationSummary *locs, Code::EntryKind entry_kind=Code::EntryKind::kNormal)
void set_intrinsic_slow_path_label(compiler::Label *label)
void Bailout(const char *reason)
void ArchSpecificInitialization()
const ZoneGrowableArray< const ICData * > & deopt_id_to_ic_data() const
void GenerateNonLazyDeoptableStubCall(const InstructionSource &source, const Code &stub, UntaggedPcDescriptors::Kind kind, LocationSummary *locs, ObjectPool::SnapshotBehavior snapshot_behavior=compiler::ObjectPoolBuilderEntry::kSnapshotable)
void GenerateAssertAssignable(CompileType *receiver_type, const InstructionSource &source, intptr_t deopt_id, Environment *env, const String &dst_name, LocationSummary *locs)
bool CanOptimizeFunction() const
void FinalizeCodeSourceMap(const Code &code)
GrowableArray< const Field * > & used_static_fields()
ArrayPtr CreateDeoptInfo(compiler::Assembler *assembler)
void GenerateStringTypeCheck(Register kClassIdReg, compiler::Label *is_instance_lbl, compiler::Label *is_not_instance_lbl)
void EmitInstanceCallAOT(const ICData &ic_data, intptr_t deopt_id, const InstructionSource &source, LocationSummary *locs, Code::EntryKind entry_kind=Code::EntryKind::kNormal, bool receiver_can_be_smi=true)
void SpecialStatsEnd(intptr_t tag)
const GrowableArray< BlockInfo * > & block_info() const
bool NeedsEdgeCounter(BlockEntryInstr *block)
static bool SupportsUnboxedSimd128()
void FinalizePcDescriptors(const Code &code)
void EmitYieldPositionMetadata(const InstructionSource &source, intptr_t yield_index)
void StatsEnd(Instruction *instr)
void GenerateStubCall(const InstructionSource &source, const Code &stub, UntaggedPcDescriptors::Kind kind, LocationSummary *locs, intptr_t deopt_id, Environment *env)
ArrayPtr InliningIdToFunction() const
void EmitMove(Location dst, Location src, TemporaryRegisterAllocator *temp)
void EmitCallsiteMetadata(const InstructionSource &source, intptr_t deopt_id, UntaggedPcDescriptors::Kind kind, LocationSummary *locs, Environment *env)
static bool CanConvertInt64ToDouble()
void GenerateInstanceOf(const InstructionSource &source, intptr_t deopt_id, Environment *env, const AbstractType &type, LocationSummary *locs)
compiler::Assembler * assembler() const
void EmitMoveConst(const compiler::ffi::NativeLocation &dst, Location src, Representation src_type, TemporaryRegisterAllocator *temp)
const ICData * GetOrAddStaticCallICData(intptr_t deopt_id, const Function &target, const Array &arguments_descriptor, intptr_t num_args_tested, ICData::RebindRule rebind_rule)
bool intrinsic_mode() const
void AddCurrentDescriptor(UntaggedPcDescriptors::Kind kind, intptr_t deopt_id, const InstructionSource &source)
compiler::Label * NextNonEmptyLabel() const
void GenerateCallerChecksForAssertAssignable(CompileType *receiver_type, const AbstractType &dst_type, compiler::Label *done)
void EndCodeSourceRange(const InstructionSource &source)
void SpecialStatsBegin(intptr_t tag)
void EmitNativeMove(const compiler::ffi::NativeLocation &dst, const compiler::ffi::NativeLocation &src, TemporaryRegisterAllocator *temp)
compiler::Label * intrinsic_slow_path_label() const
void AddNullCheck(const InstructionSource &source, const String &name)
void GenerateStaticCall(intptr_t deopt_id, const InstructionSource &source, const Function &function, ArgumentsInfo args_info, LocationSummary *locs, const ICData &ic_data_in, ICData::RebindRule rebind_rule, Code::EntryKind entry_kind=Code::EntryKind::kNormal)
Environment * SlowPathEnvironmentFor(Instruction *inst, intptr_t num_slow_path_args)
void BeginCodeSourceRange(const InstructionSource &source)
bool ForceOptimize() const
static bool UseUnboxedRepresentation()
virtual bool CanCallDart() const
virtual void EmitSharedStubCall(FlowGraphCompiler *compiler, bool save_fpu_registers)
virtual intptr_t GetNumberOfArgumentsForRuntimeCall()
virtual void PushArgumentsForRuntimeCall(FlowGraphCompiler *compiler)
virtual const char * name()
LateInitializationErrorSlowPath(Instruction *instruction)
void ReleaseTemporary() override
Register AllocateTemporary() override
static CodePtr GetStub(FlowGraphCompiler *compiler, CheckNullInstr::ExceptionType exception_type, bool save_fpu_registers)
NullErrorSlowPath(CheckNullInstr *instruction)
void EmitSharedStubCall(FlowGraphCompiler *compiler, bool save_fpu_registers) override
void AddMetadataForRuntimeCall(FlowGraphCompiler *compiler) override
const char * name() override
CheckNullInstr::ExceptionType exception_type() const
const Function & function() const
virtual void EmitSharedStubCall(FlowGraphCompiler *compiler, bool save_fpu_registers)
virtual void PushArgumentsForRuntimeCall(FlowGraphCompiler *compiler)
virtual intptr_t GetNumberOfArgumentsForRuntimeCall()
virtual const char * name()
RangeErrorSlowPath(GenericCheckBoundInstr *instruction)
virtual void EmitNativeCode(FlowGraphCompiler *compiler)=0
void GenerateCode(FlowGraphCompiler *compiler)
Instruction * instruction() const
compiler::Label * entry_label()
compiler::Label * exit_label()
SlowPathCode(Instruction *instruction)
static constexpr intptr_t kMaxInputs
TemplateSlowPathCode(T *instruction)
virtual void ReleaseTemporary()=0
virtual ~TemporaryRegisterAllocator()
virtual Register AllocateTemporary()=0
static Thread * Current()
IsolateGroup * isolate_group() const
virtual void EmitCodeAtSlowPathEntry(FlowGraphCompiler *compiler)
ThrowErrorSlowPathCode(Instruction *instruction, const RuntimeEntry &runtime_entry)
virtual intptr_t GetNumberOfArgumentsForRuntimeCall()
virtual void EmitNativeCode(FlowGraphCompiler *compiler)
virtual void EmitSharedStubCall(FlowGraphCompiler *compiler, bool save_fpu_registers)
virtual void AddMetadataForRuntimeCall(FlowGraphCompiler *compiler)
virtual void PushArgumentsForRuntimeCall(FlowGraphCompiler *compiler)
virtual const char * name()=0
static constexpr intptr_t kInvalidYieldIndex
static int SNPrint(char *str, size_t size, const char *format,...) PRINTF_ATTRIBUTE(3
virtual const char * name()
virtual void PushArgumentsForRuntimeCall(FlowGraphCompiler *compiler)
virtual intptr_t GetNumberOfArgumentsForRuntimeCall()
virtual void EmitSharedStubCall(FlowGraphCompiler *compiler, bool save_fpu_registers)
WriteErrorSlowPath(CheckWritableInstr *instruction)
ElementType * Alloc(intptr_t length)
FlutterSemanticsFlag flags
Dart_NativeFunction function
const char *const function_name
const char * DeoptReasonToCString(ICData::DeoptReasonId deopt_reason)
static constexpr intptr_t kInvalidTryIndex