20#if defined(INCLUDE_IL_PRINTER)
22 display_sorted_ic_data,
24 "Calls display a unary, sorted-by count form of ICData");
25DEFINE_FLAG(
bool, print_environments,
false,
"Print SSA environments.");
27 print_flow_graph_as_json,
29 "Use machine readable output when printing IL graphs.");
30DEFINE_FLAG(
bool, print_redundant_il,
false,
"Print redundant IL instructions");
34static bool IsRedundant(Instruction* instr) {
35 if (
auto constant = instr->AsConstant()) {
36 return !constant->HasUses();
37 }
else if (
auto move = instr->AsParallelMove()) {
38 return move->IsRedundant();
44static bool ShouldPrintInstruction(Instruction* instr) {
45 return FLAG_print_redundant_il || !IsRedundant(instr);
48class IlTestPrinter :
public AllStatic {
50 static void PrintGraph(
const char* phase, FlowGraph* flow_graph) {
53 writer.PrintProperty(
"p", phase);
54 writer.PrintProperty(
"f", flow_graph->function().ToFullyQualifiedCString());
55 writer.OpenArray(
"b");
56 for (
auto block : flow_graph->reverse_postorder()) {
57 PrintBlock(&writer, block);
60 const auto& codegen_order = *flow_graph->CodegenBlockOrder();
61 if (!codegen_order.is_empty() &&
62 (&codegen_order != &flow_graph->reverse_postorder())) {
63 writer.OpenArray(
"cbo");
64 const auto block_count = flow_graph->reverse_postorder().length();
65 for (
auto block : codegen_order) {
66 writer.PrintValue64((
block_count - 1) - block->postorder_number());
70 writer.OpenObject(
"desc");
71 AttributesSerializer(&writer).WriteDescriptors();
73 writer.OpenObject(
"flags");
74 writer.PrintPropertyBool(
"nnbd",
true);
80 static void PrintBlock(JSONWriter* writer, BlockEntryInstr* block) {
82 writer->PrintProperty64(
"b", block->block_id());
83 writer->PrintProperty(
"o", block->DebugName());
84 if (
auto block_with_defs = block->AsBlockEntryWithInitialDefs()) {
85 if (block_with_defs->initial_definitions() !=
nullptr &&
86 block_with_defs->initial_definitions()->length() > 0) {
87 writer->OpenArray(
"d");
88 for (
auto defn : *block_with_defs->initial_definitions()) {
89 if (ShouldPrintInstruction(defn)) {
90 PrintInstruction(writer, defn);
96 writer->OpenArray(
"is");
97 if (
auto join = block->AsJoinEntry()) {
98 for (PhiIterator it(
join); !it.Done(); it.Advance()) {
99 if (ShouldPrintInstruction(it.Current())) {
100 PrintInstruction(writer, it.Current());
104 for (
auto instr : block->instructions()) {
105 if (instr->ArgumentCount() != 0 && instr->GetMoveArguments() !=
nullptr) {
106 for (
auto move_arg : *(instr->GetMoveArguments())) {
107 PrintInstruction(writer, move_arg);
110 if (ShouldPrintInstruction(instr) && !instr->IsMoveArgument()) {
111 PrintInstruction(writer, instr);
114 writer->CloseArray();
115 writer->CloseObject();
118 static void PrintInstruction(JSONWriter* writer,
120 const char*
name =
nullptr) {
121 writer->OpenObject(
name);
122 if (
auto defn = instr->AsDefinition()) {
123 if (defn->ssa_temp_index() != -1) {
124 writer->PrintProperty(
"v", defn->ssa_temp_index());
127 if (defn->HasType()) {
128 writer->OpenObject(
"T");
129 defn->Type()->PrintTo(writer);
130 writer->CloseObject();
133 writer->PrintProperty(
"o", instr->DebugName());
134 if (
auto branch = instr->AsBranch()) {
135 PrintInstruction(writer, branch->comparison(),
"cc");
137 if (instr->InputCount() != 0) {
138 writer->OpenArray(
"i");
139 for (intptr_t
i = 0;
i < instr->InputCount();
i++) {
140 writer->PrintValue(instr->InputAt(
i)->definition()->ssa_temp_index());
142 writer->CloseArray();
143 }
else if (instr->ArgumentCount() != 0 &&
144 instr->GetMoveArguments() !=
nullptr) {
145 writer->OpenArray(
"i");
146 for (intptr_t
i = 0;
i < instr->ArgumentCount();
i++) {
148 instr->ArgumentValueAt(
i)->definition()->ssa_temp_index());
150 writer->CloseArray();
152 AttributesSerializer serializer(writer);
153 instr->Accept(&serializer);
155 if (instr->SuccessorCount() > 0) {
156 writer->OpenArray(
"s");
157 for (
auto succ : instr->successors()) {
158 writer->PrintValue(succ->block_id());
160 writer->CloseArray();
162 writer->CloseObject();
165 template <
typename T>
166 class HasGetAttributes {
167 template <
typename U>
168 static std::true_type
test(
decltype(&U::GetAttributes));
169 template <
typename U>
170 static std::false_type
test(...);
173 static constexpr bool value =
decltype(test<T>(
nullptr))
::value;
176 class AttributesSerializer :
public InstructionVisitor {
178 explicit AttributesSerializer(JSONWriter* writer) : writer_(writer) {}
180 void WriteDescriptors() {
181#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
182 WriteDescriptor<ShortName##Instr>(#ShortName);
186#undef DECLARE_VISIT_INSTRUCTION
189#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
190 virtual void Visit##ShortName(ShortName##Instr* instr) { Write(instr); }
194#undef DECLARE_VISIT_INSTRUCTION
197 void WriteAttribute(
const char*
value) { writer_->PrintValue(
value); }
199 void WriteAttribute(intptr_t
value) { writer_->PrintValue(
value); }
201 void WriteAttribute(
bool value) { writer_->PrintValueBool(
value); }
211 static const char* LocationKindAsString(
const Location& loc) {
212 if (loc.IsConstant()) {
214 }
else if (loc.IsPairLocation()) {
215 auto pair = loc.AsPairLocation();
217 "(%s, %s)", LocationKindAsString(pair->At(0)),
218 LocationKindAsString(pair->At(0)));
220 switch (loc.kind()) {
224 return "stack(word)";
228 return "stack(f128)";
239 void WriteAttribute(
const Location& loc) {
240 writer_->PrintValue(LocationKindAsString(loc));
243 void WriteAttribute(
const Slot* slot) { writer_->PrintValue(slot->Name()); }
245 void WriteAttribute(
const Function*
function) {
246 writer_->PrintValue(
function->QualifiedUserVisibleNameCString());
249 void WriteAttribute(
const Object* obj) {
251 writer_->PrintValueNull();
252 }
else if (obj->IsBool()) {
253 writer_->PrintValueBool(Bool::Cast(*obj).value());
254 }
else if (obj->IsInteger()) {
255 auto value = Integer::Cast(*obj).AsInt64Value();
259 writer_->buffer()->Printf(
"%" Pd64 "",
value);
260 }
else if (obj->IsString()) {
261 const auto& str = String::Cast(*obj);
262 writer_->PrintValueStr(str, 0, str.Length());
265 writer_->PrintfValue(
"Instance of %s", cls.UserVisibleNameCString());
269 template <
typename... Ts>
270 void WriteTuple(
const std::tuple<Ts...>& tuple) {
272 [&](Ts
const&... elements) { (WriteAttribute(elements), ...); },
276 template <
typename T,
278 void Write(
T* instr) {
279 writer_->OpenArray(
"d");
280 WriteTuple(instr->GetAttributes());
281 writer_->CloseArray();
284 void Write(Instruction* instr) {
288 void WriteAttributeName(
const char* str) {
298 const intptr_t
start = str[0] ==
'&' ? 1 : 0;
299 intptr_t
end = strlen(str);
300 switch (str[end - 1]) {
313 writer_->PrintValue(str + start, end - start);
316 template <
typename... Ts>
317 void WriteAttributeNames(
const std::tuple<Ts...>& tuple) {
319 [&](Ts
const&... elements) { (WriteAttributeName(elements), ...); },
323 template <
typename T>
324 void WriteDescriptor(
327 writer_->OpenArray(
name);
328 WriteAttributeNames(T::GetAttributeNames());
329 writer_->CloseArray();
332 template <
typename T>
333 void WriteDescriptor(
343 uint8_t** compiler_pass_filter ) {
344 return compiler::PrintFilter::ShouldPrint(
function, compiler_pass_filter);
349 if (FLAG_print_flow_graph_as_json) {
350 IlTestPrinter::PrintGraph(phase, flow_graph);
354 printer.PrintBlocks();
361 bool print_locations) {
366 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
367 Instruction* current = it.Current();
370 if (!ShouldPrintInstruction(current)) {
380 if (!function_.
IsNull()) {
387 const ArgumentsDescriptor args_desc(args_desc_array);
388 THR_Print(
", %s", args_desc.ToCString());
393 for (intptr_t
i = 0;
i < block_order_.length(); ++
i) {
403 bool print_locations) {
405 BufferFormatter
f(str,
sizeof(str));
409 if (!instr->IsBlockEntry()) {
412 if (
auto*
const block = instr->AsBlockEntryWithInitialDefs()) {
413 block->PrintBlockHeaderTo(&
f);
420 block->PrintInitialDefinitionsTo(&
f,
callback);
424 if (FLAG_print_environments && (instr->env() !=
nullptr)) {
425 instr->env()->PrintTo(&
f);
427 if (print_locations && (instr->HasLocs())) {
428 instr->locs()->PrintTo(&
f);
430 if (FLAG_trace_inlining_intervals) {
431 f.Printf(
" iid: %" Pd "", instr->inlining_id());
437 TokenPosition token_pos,
439 const AbstractType& dst_type,
440 const String& dst_name,
442 const char* compile_type_name =
"unknown";
443 if (
value !=
nullptr &&
value->reaching_type_ !=
nullptr) {
444 compile_type_name =
value->reaching_type_->ToCString();
447 "%s type check: compile type %s is %s specific than "
448 "type '%s' of '%s'.\n",
449 eliminated ?
"Eliminated" :
"Generated", compile_type_name,
450 eliminated ?
"more" :
"not more", dst_type.NameCString(),
451 dst_name.ToCString());
454static void PrintTargetsHelper(BaseTextBuffer*
f,
455 const CallTargets& targets,
456 intptr_t num_checks_to_print) {
457 f->AddString(
" Targets[");
458 f->Printf(
"%" Pd ": ", targets.length());
461 (num_checks_to_print > targets.length())) {
462 num_checks_to_print = targets.length();
464 for (intptr_t
i = 0;
i < num_checks_to_print;
i++) {
465 const CidRange& range = targets[
i];
466 const auto target_info = targets.TargetAt(
i);
467 const intptr_t
count = target_info->count;
468 target = target_info->target->ptr();
472 if (range.IsSingleCid()) {
476 f->Printf(
" cid %" Pd " cnt:%" Pd " trgt:'%s'", range.cid_start,
count,
477 target.ToQualifiedCString());
480 f->Printf(
"cid %" Pd "-%" Pd " %s", range.cid_start, range.cid_end,
482 f->Printf(
" cnt:%" Pd " trgt:'%s'",
count,
target.ToQualifiedCString());
485 if (target_info->exactness.IsTracking()) {
486 f->Printf(
" %s", target_info->exactness.ToCString());
489 if (num_checks_to_print < targets.length()) {
495static void PrintCidsHelper(BaseTextBuffer*
f,
497 intptr_t num_checks_to_print) {
498 f->AddString(
" Cids[");
499 f->Printf(
"%" Pd ": ", targets.length());
501 (num_checks_to_print > targets.length())) {
502 num_checks_to_print = targets.length();
504 for (intptr_t
i = 0;
i < num_checks_to_print;
i++) {
505 const CidRange& range = targets[
i];
512 if (range.IsSingleCid()) {
513 f->Printf(
" cid %" Pd, range.cid_start);
515 f->Printf(
" cid %" Pd "-%" Pd, range.cid_start, range.cid_end);
518 if (num_checks_to_print < targets.length()) {
524static void PrintICDataHelper(BaseTextBuffer*
f,
525 const ICData& ic_data,
526 intptr_t num_checks_to_print) {
527 f->AddString(
" IC[");
528 if (ic_data.is_tracking_exactness()) {
533 f->Printf(
"%" Pd ": ", ic_data.NumberOfChecks());
536 (num_checks_to_print > ic_data.NumberOfChecks())) {
537 num_checks_to_print = ic_data.NumberOfChecks();
539 for (intptr_t
i = 0;
i < num_checks_to_print;
i++) {
540 GrowableArray<intptr_t> class_ids;
541 ic_data.GetCheckAt(
i, &class_ids, &
target);
542 const intptr_t
count = ic_data.GetCountAt(
i);
546 for (intptr_t k = 0; k < class_ids.length(); k++) {
554 f->Printf(
" cnt:%" Pd " trgt:'%s'",
count,
target.ToQualifiedCString());
555 if (ic_data.is_tracking_exactness()) {
556 f->Printf(
" %s", ic_data.GetExactnessAt(
i).ToCString());
559 if (num_checks_to_print < ic_data.NumberOfChecks()) {
565static void PrintICDataSortedHelper(BaseTextBuffer*
f,
566 const ICData& ic_data_orig) {
567 const ICData& ic_data =
569 f->Printf(
" IC[n:%" Pd "; ", ic_data.NumberOfChecks());
570 for (intptr_t
i = 0;
i < ic_data.NumberOfChecks();
i++) {
571 const intptr_t
count = ic_data.GetCountAt(
i);
572 const intptr_t
cid = ic_data.GetReceiverClassIdAt(
i);
581 intptr_t num_checks_to_print) {
584 PrintICDataHelper(&
f, ic_data, num_checks_to_print);
591 intptr_t num_checks_to_print) {
594 PrintTargetsHelper(&
f, targets, num_checks_to_print);
599static void PrintUse(BaseTextBuffer*
f,
const Definition& definition) {
600 if (definition.HasSSATemp()) {
601 f->Printf(
"v%" Pd "", definition.ssa_temp_index());
602 }
else if (definition.HasTemp()) {
603 f->Printf(
"t%" Pd "", definition.temp_index());
624void Instruction::PrintOperandsTo(BaseTextBuffer*
f)
const {
626 if (
i > 0)
f->AddString(
", ");
648 }
else if (type_ !=
nullptr) {
654void CheckNullInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
655 Definition::PrintOperandsTo(
f);
658 f->AddString(
", NoSuchMethodError");
661 f->AddString(
", ArgumentError");
664 f->AddString(
", CastError");
669void Definition::PrintOperandsTo(BaseTextBuffer*
f)
const {
671 if (
i > 0)
f->AddString(
", ");
678void RedefinitionInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
679 Definition::PrintOperandsTo(
f);
680 if (constrained_type_ !=
nullptr) {
681 f->Printf(
" ^ %s", constrained_type_->ToCString());
685void ReachabilityFenceInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
699 if ((reaching_type_ !=
nullptr) && (reaching_type_ !=
definition()->type_)) {
705void ConstantInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
707 const char* new_line = strchr(cstr,
'\n');
708 if (new_line ==
nullptr) {
709 f->Printf(
"#%s", cstr);
711 const intptr_t
pos = new_line - cstr;
715 f->Printf(
"#%s\\n...",
buffer);
719void ConstraintInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
734 if (range ==
nullptr)
return "[_|_, _|_]";
745 f->Printf(
"v%" Pd "",
746 reinterpret_cast<Definition*
>(value_)->ssa_temp_index());
747 if (offset_ != 0)
f->Printf(
"%+" Pd64 "", offset_);
750 f->Printf(
"%" Pd64 "", value_);
765void MakeTempInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {}
767void DropTempsInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
769 if (
value() !=
nullptr) {
775void AssertAssignableInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
780 f->AddString(
" instantiator_type_args(");
782 f->AddString(
"), function_type_args(");
787void AssertSubtypeInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
793 f->AddString(
", instantiator_type_args(");
795 f->AddString(
"), function_type_args(");
800void AssertBooleanInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
804void ClosureCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
805 if (FLAG_precompiled_mode) {
806 f->AddString(
" closure=");
808 f->AddString(
" function=");
818void InstanceCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
825 if (FLAG_display_sorted_ic_data) {
826 PrintICDataSortedHelper(
f, *
ic_data());
834 if (
entry_kind() == Code::EntryKind::kUnchecked) {
835 f->AddString(
" using unchecked entrypoint");
839void PolymorphicInstanceCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
847 f->AddString(
" COMPLETE");
849 if (
entry_kind() == Code::EntryKind::kUnchecked) {
850 f->AddString(
" using unchecked entrypoint");
854void DispatchTableCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
857 f->AddString(
" cid=");
866void StrictCompareInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
872 f->Printf(
", with number check");
876void TestCidsInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
880 for (intptr_t
i = 0;
i <
length;
i += 2) {
887 f->AddString(
"else deoptimize ");
894void TestRangeInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
896 f->Printf(
" %s [%" Pd "-%" Pd "]", kind() == Token::kIS ?
"in" :
"not in",
900void EqualityCompareInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
906void StaticCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
910 if (
i > 0)
f->AddString(
", ");
913 if (
entry_kind() == Code::EntryKind::kUnchecked) {
914 f->AddString(
", using unchecked entrypoint");
917 f->Printf(
", recognized_kind = %s",
925void CachableIdempotentCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
929 if (
i > 0)
f->AddString(
", ");
934void LoadLocalInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
938void StoreLocalInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
943void NativeCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
947void GuardFieldInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
949 field().GuardedPropertiesAsCString());
953void StoreFieldInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
965 f->AddString(
", NoStoreBarrier");
968 f->AddString(
", MayStoreInnerPointer");
972void IfThenElseInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
974 f->Printf(
" ? %" Pd " : %" Pd, if_true_, if_false_);
977void LoadStaticFieldInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
980 f->AddString(
", CallsInitializer");
984void StoreStaticFieldInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
989void InstanceOfInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
991 f->Printf(
" IS %s,",
type().NameCString());
992 f->AddString(
" instantiator_type_args(");
994 f->AddString(
"), function_type_args(");
999void RelationalOpInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1006void AllocationInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1007 Definition::PrintOperandsTo(
f);
1012 f->AddString(
"<not-aliased>");
1016void AllocateObjectInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1017 f->Printf(
"cls=%s",
cls().ScrubbedNameCString());
1021 AllocationInstr::PrintOperandsTo(
f);
1024void MaterializeObjectInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1025 f->Printf(
"%s", cls_.ScrubbedNameCString());
1028 f->Printf(
"%s: ", slots_[
i]->
Name());
1033void LoadFieldInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1037 f->AddString(
", CallsInitializer");
1040 f->AddString(
", MayLoadInnerPointer");
1044void LoadUntaggedInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1049void CalculateElementAddressInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1050 Definition::PrintOperandsTo(
f);
1054void InstantiateTypeInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1056 f->Printf(
"%s,", type_name.ToCString());
1057 f->AddString(
" instantiator_type_args(");
1059 f->AddString(
"), function_type_args(");
1064void InstantiateTypeArgumentsInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1066 f->AddString(
", instantiator_type_args(");
1068 f->AddString(
"), function_type_args(");
1076void AllocateContextInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1081 TemplateAllocation::PrintOperandsTo(
f);
1084void AllocateUninitializedContextInstr::PrintOperandsTo(
1085 BaseTextBuffer*
f)
const {
1090 TemplateAllocation::PrintOperandsTo(
f);
1093void TruncDivModInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1094 Definition::PrintOperandsTo(
f);
1097void ExtractNthOutputInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1098 f->Printf(
"Extract %" Pd " from ",
index());
1099 Definition::PrintOperandsTo(
f);
1102void UnboxLaneInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1103 Definition::PrintOperandsTo(
f);
1104 f->Printf(
", lane %" Pd,
lane());
1107void BoxLanesInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1108 Definition::PrintOperandsTo(
f);
1111void UnaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1116void BinaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1119 f->AddString(
" [tr]");
1121 f->AddString(
" [-o]");
1129void BinaryDoubleOpInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1136void DoubleTestOpInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1138 case MethodRecognizer::kDouble_getIsNaN:
1139 f->AddString(
"IsNaN ");
1141 case MethodRecognizer::kDouble_getIsInfinite:
1142 f->AddString(
"IsInfinite ");
1144 case MethodRecognizer::kDouble_getIsNegative:
1145 f->AddString(
"IsNegative ");
1153static const char*
const simd_op_kind_string[] = {
1154#define CASE(Arity, Mask, Name, ...) #Name,
1159void SimdOpInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1160 f->Printf(
"%s", simd_op_kind_string[
kind()]);
1162 f->Printf(
", mask = %" Pd "",
mask());
1170void UnaryDoubleOpInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1175void LoadClassIdInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1176 if (!input_can_be_smi_) {
1177 f->AddString(
"<non-smi> ");
1182void CheckClassIdInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1188 if (
cids().IsSingleCid()) {
1189 f->Printf(
", %s",
name.ToCString());
1194 f->Printf(
", cid %" Pd "-%" Pd " %s-%s",
cids().cid_start,
cids().cid_end,
1195 name.ToCString(), name2.ToCString());
1199void HashIntegerOpInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1201 f->AddString(
"smi ");
1207void CheckClassInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1211 f->AddString(
" nullcheck");
1215void CheckConditionInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1219void InvokeMathCFunctionInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1221 Definition::PrintOperandsTo(
f);
1236 if (
i > 0)
f->AddString(
", ");
1240 if (phis_ !=
nullptr) {
1242 for (intptr_t
i = 0;
i < phis_->length(); ++
i) {
1243 if ((*phis_)[
i] ==
nullptr)
continue;
1244 f->AddString(
"\n ");
1245 (*phis_)[
i]->PrintTo(
f);
1247 f->AddString(
"\n}");
1262 if (
i > 0)
f->AddString(
", ");
1266 if (phis_ !=
nullptr) {
1268 for (intptr_t
i = 0;
i < phis_->length(); ++
i) {
1269 if ((*phis_)[
i] ==
nullptr)
continue;
1270 f->AddString(
"\n ");
1271 (*phis_)[
i]->PrintTo(
f);
1273 f->AddString(
"\n}");
1288 f->AddString(
is_alive() ?
" alive" :
" dead");
1299 f->Printf(
" %s", TypeAsCString());
1303void UnboxIntegerInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1305 f->AddString(
"[tr], ");
1308 f->AddString(
"[guard-inputs], ");
1310 f->AddString(
"[non-speculative], ");
1312 Definition::PrintOperandsTo(
f);
1315void IntConverterInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1319 Definition::PrintOperandsTo(
f);
1322void BitCastInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1323 Definition::PrintOperandsTo(
f);
1328void ParameterInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1332void CheckStackOverflowInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1357 const GrowableArray<Definition*>& defns = initial_definitions_;
1358 if (defns.length() > 0) {
1360 for (intptr_t
i = 0;
i < defns.length(); ++
i) {
1361 Definition*
const def = defns[
i];
1363 if (!ShouldPrintInstruction(def)) {
1366 f->AddString(
"\n ");
1370 f->AddString(
"\n}");
1399void FfiCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1400 f->AddString(
" pointer=");
1402 if (marshaller_.ReturnsCompound()) {
1403 f->AddString(
", compound_return_typed_data=");
1406 intptr_t def_index = 0;
1407 for (intptr_t arg_index = 0; arg_index < marshaller_.num_args();
1409 const auto& arg_location = marshaller_.Location(arg_index);
1410 const bool is_compound = arg_location.container_type().IsCompound();
1411 const intptr_t num_defs = marshaller_.NumDefinitions(arg_index);
1413 if (is_compound)
f->AddString(
"(");
1414 for (intptr_t
i = 0;
i < num_defs;
i++) {
1416 if ((
i + 1) < num_defs)
f->AddString(
", ");
1419 if (is_compound)
f->AddString(
")");
1420 f->AddString(
" (@");
1421 arg_location.PrintTo(
f);
1426void LeafRuntimeCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1427 f->AddString(
"target_address=");
1429 for (intptr_t
i = 0, n = argument_representations_.length();
i < n; ++
i) {
1435void NativeReturnInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1436 if (marshaller_.NumReturnDefinitions() == 1) {
1447 f->AddString(
" (@");
1452void NativeParameterInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1454 marshaller_.Location(marshaller_.ArgumentIndex(def_index_)).PrintTo(
f);
1455 f->AddString(
" at ");
1457 marshaller_.NativeLocationOfNativeParameter(def_index_).PrintTo(
f);
1461 f->Printf(
"B%" Pd "[target catch try_idx %" Pd " catch_try_idx %" Pd "]",
1469void LoadIndexedUnsafeInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1475void StoreIndexedUnsafeInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1482void LoadIndexedInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1485 if (!cls.IsNull()) {
1486 f->Printf(
"[%s] ", cls.ScrubbedNameCString());
1490 Instruction::PrintOperandsTo(
f);
1493void StoreIndexedInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1496 if (!cls.IsNull()) {
1497 f->Printf(
"[%s] ", cls.ScrubbedNameCString());
1501 Instruction::PrintOperandsTo(
f);
1503 f->AddString(
", NoStoreBarrier");
1507void MemoryCopyInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1508 Instruction::PrintOperandsTo(
f);
1511 if (!cls.IsNull()) {
1512 f->Printf(
", dest_cid=%s (%d)", cls.ScrubbedNameCString(), dest_cid_);
1514 f->Printf(
", dest_cid=%d", dest_cid_);
1517 f->Printf(
" [untagged]");
1520 if (!cls.IsNull()) {
1521 f->Printf(
", src_cid=%s (%d)", cls.ScrubbedNameCString(), src_cid_);
1523 f->Printf(
", src_cid=%d", src_cid_);
1526 f->Printf(
" [untagged]");
1532 f->AddString(
", unboxed_inputs");
1535 f->AddString(
", can_overlap");
1539void TailCallInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1540 const char*
name =
"<unknown code>";
1541 if (code_.IsStubCode()) {
1545 if (owner.IsFunction()) {
1547 .ToFullyQualifiedCString();
1550 f->Printf(
"%s(",
name);
1555void Call1ArgStubInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1556 const char*
name =
"";
1559 name =
"CloneSuspendState";
1565 name =
"InitAsyncStar";
1568 name =
"InitSyncStar";
1571 name =
"FfiAsyncCallbackSend";
1574 f->Printf(
"%s(",
name);
1579void SuspendInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1580 const char*
name =
"";
1586 name =
"AwaitWithTypeCheck";
1589 name =
"YieldAsyncStar";
1592 name =
"SuspendSyncStarAtStart";
1595 name =
"SuspendSyncStarAtYield";
1598 f->Printf(
"%s(",
name);
1599 Definition::PrintOperandsTo(
f);
1603void MoveArgumentInstr::PrintOperandsTo(BaseTextBuffer*
f)
const {
1624 f->AddString(
"igoto:(");
1632 f->AddString(
"if ");
1641 for (intptr_t
i = 0;
i < moves_.length();
i++) {
1642 if (
i != 0)
f->AddString(
", ");
1643 moves_[
i]->dest().PrintTo(
f);
1644 f->AddString(
" <- ");
1645 moves_[
i]->src().PrintTo(
f);
1651 f->Printf(
" [%s]", scan_flags_field_.Name());
1655 f->AddString(
" env={ ");
1657 for (intptr_t
i = 0;
i < values_.
length(); ++
i) {
1658 if (
i > 0)
f->AddString(
", ");
1659 if (values_[
i]->definition()->IsMoveArgument()) {
1660 f->Printf(
"a%d", arg_count++);
1662 values_[
i]->PrintTo(
f);
1664 if ((locations_ !=
nullptr) && !locations_[
i].IsInvalid()) {
1671 if (outer_ !=
nullptr) outer_->
PrintTo(
f);
1676 BufferFormatter bf(
buffer, 1024);
1688 bool print_locations) {
1702 bool print_locations) {
1711 intptr_t num_checks_to_print) {
1717 uint8_t** compiler_pass_filter ) {
static int block_count(const SkSBlockAllocator< N > &pool)
static bool apply(Pass *pass, SkRecord *record)
#define ASSERT_EQUAL(expected, actual)
intptr_t num_context_variables() const
const Class & cls() const
virtual intptr_t InputCount() const
intptr_t num_context_variables() const
virtual AliasIdentity Identity() const
const String & dst_name() const
Value * function_type_arguments() const
Value * instantiator_type_arguments() const
Value * function_type_arguments() const
Value * super_type() const
Value * instantiator_type_arguments() const
Token::Kind op_kind() const
bool can_overflow() const
Token::Kind op_kind() const
bool is_truncating() const
Representation to() const
Representation from() const
intptr_t try_index() const
ParallelMoveInstr * parallel_move() const
bool HasParallelMove() const
intptr_t block_id() const
intptr_t stack_depth() const
void PrintInitialDefinitionsTo(BaseTextBuffer *f, std::function< void(BaseTextBuffer *f)> callback) const
virtual void PrintBlockHeaderTo(BaseTextBuffer *f) const
TargetEntryInstr * false_successor() const
TargetEntryInstr * true_successor() const
ComparisonInstr * comparison() const
const Function & function() const
intptr_t index_scale() const
intptr_t catch_try_index() const
const CidRangeValue & cids() const
ComparisonInstr * comparison() const
ExceptionType exception_type() const
intptr_t stack_depth() const
intptr_t loop_depth() const
ClassPtr At(intptr_t cid) const
void PrintTo(BaseTextBuffer *f) const
const Object & value() const
Range * constraint() const
intptr_t ssa_temp_index() const
static constexpr intptr_t kNone
const Function & interface_target() const
MethodRecognizer::Kind op_kind() const
intptr_t num_temps() const
void PrintTo(BaseTextBuffer *f) const
const char * ToCString() const
intptr_t CompoundReturnTypedDataIndex() const
intptr_t TargetAddressIndex() const
static DART_FORCE_INLINE bool HasLifetimePosition(Instruction *instr)
static DART_FORCE_INLINE intptr_t GetLifetimePosition(const Instruction *instr)
static void PrintOneInstruction(Instruction *instr, bool print_locations)
static void PrintGraph(const char *phase, FlowGraph *flow_graph)
static void PrintCidRangeData(const CallTargets &ic_data, intptr_t num_checks_to_print=kPrintAll)
static bool ShouldPrint(const Function &function, uint8_t **compiler_pass_filter=nullptr)
static void PrintBlock(BlockEntryInstr *block, bool print_locations)
static constexpr intptr_t kPrintAll
FlowGraphPrinter(const FlowGraph &flow_graph, bool print_locations=false)
void PrintInstruction(Instruction *instr)
static void PrintICData(const ICData &ic_data, intptr_t num_checks_to_print=kPrintAll)
static void PrintTypeCheck(const ParsedFunction &parsed_function, TokenPosition token_pos, Value *value, const AbstractType &dst_type, const String &dst_name, bool eliminated)
const char * ToFullyQualifiedCString() const
static const char * KindToCString(UntaggedFunction::Kind kind)
bool HasSavedArgumentsDescriptor() const
UntaggedFunction::Kind kind() const
ArrayPtr saved_args_desc() const
ParallelMoveInstr * parallel_move() const
bool HasParallelMove() const
JoinEntryInstr * successor() const
const Field & field() const
ComparisonInstr * comparison() const
CompileType * result_type() const
Code::EntryKind entry_kind() const
const ICData * ic_data() const
const String & function_name() const
const AbstractType & type() const
Value * function_type_arguments() const
Value * instantiator_type_arguments() const
Value * type_arguments() const
Value * instantiator_type_arguments() const
Value * function_type_arguments() const
const Class & instantiator_class() const
Value * function_type_arguments() const
const AbstractType & type() const
Value * instantiator_type_arguments() const
virtual intptr_t InputCount() const =0
intptr_t GetDeoptId() const
virtual Value * InputAt(intptr_t i) const =0
const char * ToCString() const
virtual Representation representation() const
bool CanDeoptimize() const
Value * ArgumentValueAt(intptr_t index) const
intptr_t deopt_id() const
SpeculativeMode SpeculativeModeOfInputs() const
virtual const char * DebugName() const =0
bool is_truncating() const
Representation to() const
Representation from() const
static IsolateGroup * Current()
ClassTable * class_table() const
GrowableArray< BlockEntryInstr * > predecessors_
intptr_t TargetAddressIndex() const
const Slot & slot() const
bool IsImmutableLoad() const
InnerPointerAccess loads_inner_pointer() const
intptr_t class_id() const
Register base_reg() const
const LocalVariable & local() const
const Field & field() const
void PrintTo(BaseTextBuffer *f) const
bool unboxed_inputs() const
intptr_t element_size() const
static const char * KindToCString(Kind kind)
Location location() const
const String & native_name() const
virtual Value * InputAt(intptr_t i) const
virtual const char * ToCString() const
static ObjectPtr RawCast(ObjectPtr obj)
const Location & location() const
virtual Representation representation() const
const char * ToCString() const
void PrintTo(BaseTextBuffer *f) const
static const char * ToCString(const Range *range)
void PrintTo(BaseTextBuffer *f) const
static const char * RegisterName(Register reg)
virtual intptr_t InputCount() const
virtual Value * InputAt(intptr_t i) const
CompileType * result_type() const
const Function & function() const
Code::EntryKind entry_kind() const
InnerPointerAccess stores_inner_pointer() const
const Slot & slot() const
bool ShouldEmitStoreBarrier() const
intptr_t class_id() const
Register base_reg() const
const LocalVariable & local() const
const Field & field() const
bool needs_number_check() const
static const char * NameOfStub(uword entry_point)
@ kSuspendSyncStarAtYield
@ kSuspendSyncStarAtStart
virtual intptr_t InputCount() const
intptr_t type_args_len() const
intptr_t ArgumentCount() const
virtual Value * InputAt(intptr_t i) const
bool calls_initializer() const
const ZoneGrowableArray< intptr_t > & cid_results() const
static Thread * Current()
static const char * Str(Kind tok)
Token::Kind op_kind() const
Token::Kind op_kind() const
bool is_truncating() const
Definition * definition() const
const char * ToCString() const
intptr_t InputCount() const
Value * InputAt(intptr_t i) const
char * PrintToString(const char *format,...) PRINTF_ATTRIBUTE(2
char * MakeCopyOfString(const char *str)
ElementType * Alloc(intptr_t length)
#define THR_Print(format,...)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
void PrintTo(FlValue *v, std::ostream *os)
Dart_NativeFunction function
#define CASE(Arity, Mask, Name, Args, Result)
#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs)
#define FOR_EACH_INSTRUCTION(M)
#define SIMD_OP_LIST(M, BINARY_OP)
const intptr_t kResultIndex
DART_EXPORT bool IsNull(Dart_Handle object)
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")
static constexpr intptr_t kInvalidTryIndex
DECLARE_FLAG(bool, show_invisible_frames)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
static SkString join(const CommandLineFlags::StringArray &)
static const char * ToCString(Representation rep)