Flutter Engine
The Flutter Engine
il_printer.cc
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
6
7#include <tuple>
8
9#include "vm/class_id.h"
15#include "vm/os.h"
16#include "vm/parser.h"
17
18namespace dart {
19
20#if defined(INCLUDE_IL_PRINTER)
21DEFINE_FLAG(bool,
22 display_sorted_ic_data,
23 false,
24 "Calls display a unary, sorted-by count form of ICData");
25DEFINE_FLAG(bool, print_environments, false, "Print SSA environments.");
26DEFINE_FLAG(bool,
27 print_flow_graph_as_json,
28 false,
29 "Use machine readable output when printing IL graphs.");
30DEFINE_FLAG(bool, print_redundant_il, false, "Print redundant IL instructions");
31
32DECLARE_FLAG(bool, trace_inlining_intervals);
33
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();
39 } else {
40 return false;
41 }
42}
43
44static bool ShouldPrintInstruction(Instruction* instr) {
45 return FLAG_print_redundant_il || !IsRedundant(instr);
46}
47
48class IlTestPrinter : public AllStatic {
49 public:
50 static void PrintGraph(const char* phase, FlowGraph* flow_graph) {
51 JSONWriter writer;
52 writer.OpenObject();
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);
58 }
59 writer.CloseArray();
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());
67 }
68 writer.CloseArray();
69 }
70 writer.OpenObject("desc");
71 AttributesSerializer(&writer).WriteDescriptors();
72 writer.CloseObject();
73 writer.OpenObject("flags");
74 writer.PrintPropertyBool("nnbd", true);
75 writer.CloseObject();
76 writer.CloseObject();
77 THR_Print("%s\n", writer.ToCString());
78 }
79
80 static void PrintBlock(JSONWriter* writer, BlockEntryInstr* block) {
81 writer->OpenObject();
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);
91 }
92 }
93 writer->CloseArray();
94 }
95 }
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());
101 }
102 }
103 }
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);
108 }
109 }
110 if (ShouldPrintInstruction(instr) && !instr->IsMoveArgument()) {
111 PrintInstruction(writer, instr);
112 }
113 }
114 writer->CloseArray();
115 writer->CloseObject();
116 }
117
118 static void PrintInstruction(JSONWriter* writer,
119 Instruction* instr,
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());
125 }
126
127 if (defn->HasType()) {
128 writer->OpenObject("T");
129 defn->Type()->PrintTo(writer);
130 writer->CloseObject();
131 }
132 }
133 writer->PrintProperty("o", instr->DebugName());
134 if (auto branch = instr->AsBranch()) {
135 PrintInstruction(writer, branch->comparison(), "cc");
136 } else {
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());
141 }
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++) {
147 writer->PrintValue(
148 instr->ArgumentValueAt(i)->definition()->ssa_temp_index());
149 }
150 writer->CloseArray();
151 }
152 AttributesSerializer serializer(writer);
153 instr->Accept(&serializer);
154 }
155 if (instr->SuccessorCount() > 0) {
156 writer->OpenArray("s");
157 for (auto succ : instr->successors()) {
158 writer->PrintValue(succ->block_id());
159 }
160 writer->CloseArray();
161 }
162 writer->CloseObject();
163 }
164
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(...);
171
172 public:
173 static constexpr bool value = decltype(test<T>(nullptr))::value;
174 };
175
176 class AttributesSerializer : public InstructionVisitor {
177 public:
178 explicit AttributesSerializer(JSONWriter* writer) : writer_(writer) {}
179
180 void WriteDescriptors() {
181#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
182 WriteDescriptor<ShortName##Instr>(#ShortName);
183
185
186#undef DECLARE_VISIT_INSTRUCTION
187 }
188
189#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
190 virtual void Visit##ShortName(ShortName##Instr* instr) { Write(instr); }
191
193
194#undef DECLARE_VISIT_INSTRUCTION
195
196 private:
197 void WriteAttribute(const char* value) { writer_->PrintValue(value); }
198
199 void WriteAttribute(intptr_t value) { writer_->PrintValue(value); }
200
201 void WriteAttribute(bool value) { writer_->PrintValueBool(value); }
202
203 void WriteAttribute(Token::Kind kind) {
204 writer_->PrintValue(Token::Str(kind));
205 }
206
207 void WriteAttribute(Representation rep) {
208 writer_->PrintValue(RepresentationUtils::ToCString(rep));
209 }
210
211 static const char* LocationKindAsString(const Location& loc) {
212 if (loc.IsConstant()) {
213 return "C";
214 } else if (loc.IsPairLocation()) {
215 auto pair = loc.AsPairLocation();
217 "(%s, %s)", LocationKindAsString(pair->At(0)),
218 LocationKindAsString(pair->At(0)));
219 } else {
220 switch (loc.kind()) {
222 return ".";
224 return "stack(word)";
226 return "stack(f64)";
228 return "stack(f128)";
230 return "reg(cpu)";
232 return "reg(fpu)";
233 default:
234 return "?";
235 }
236 }
237 }
238
239 void WriteAttribute(const Location& loc) {
240 writer_->PrintValue(LocationKindAsString(loc));
241 }
242
243 void WriteAttribute(const Slot* slot) { writer_->PrintValue(slot->Name()); }
244
245 void WriteAttribute(const Function* function) {
246 writer_->PrintValue(function->QualifiedUserVisibleNameCString());
247 }
248
249 void WriteAttribute(const Object* obj) {
250 if (obj->IsNull()) {
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();
256 // PrintValue64 and PrintValue will check if integer is representable
257 // as a JS number, which is too strict. We don't actually need
258 // such checks because we only load resulting JSON in Dart.
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());
263 } else {
264 const auto& cls = Class::Handle(obj->clazz());
265 writer_->PrintfValue("Instance of %s", cls.UserVisibleNameCString());
266 }
267 }
268
269 template <typename... Ts>
270 void WriteTuple(const std::tuple<Ts...>& tuple) {
272 [&](Ts const&... elements) { (WriteAttribute(elements), ...); },
273 tuple);
274 }
275
276 template <typename T,
278 void Write(T* instr) {
279 writer_->OpenArray("d");
280 WriteTuple(instr->GetAttributes());
281 writer_->CloseArray();
282 }
283
284 void Write(Instruction* instr) {
285 // Default, do nothing.
286 }
287
288 void WriteAttributeName(const char* str) {
289 ASSERT(str != nullptr);
290 // To simplify the declaring side, we assume the string might be directly
291 // stringized from one of the following expression forms:
292 //
293 // * &name()
294 // * name()
295 // * name_
296 //
297 // Remove the non-name parts of the above before printing.
298 const intptr_t start = str[0] == '&' ? 1 : 0;
299 intptr_t end = strlen(str);
300 switch (str[end - 1]) {
301 case ')':
302 ASSERT(end >= 2);
303 ASSERT_EQUAL(str[end - 2], '(');
304 end -= 2;
305 break;
306 case '_':
307 // Strip off the final _ from a direct private field access.
308 end -= 1;
309 break;
310 default:
311 break;
312 }
313 writer_->PrintValue(str + start, end - start);
314 }
315
316 template <typename... Ts>
317 void WriteAttributeNames(const std::tuple<Ts...>& tuple) {
319 [&](Ts const&... elements) { (WriteAttributeName(elements), ...); },
320 tuple);
321 }
322
323 template <typename T>
324 void WriteDescriptor(
325 const char* name,
326 typename std::enable_if_t<HasGetAttributes<T>::value>* = nullptr) {
327 writer_->OpenArray(name);
328 WriteAttributeNames(T::GetAttributeNames());
329 writer_->CloseArray();
330 }
331
332 template <typename T>
333 void WriteDescriptor(
334 const char* name,
335 typename std::enable_if_t<!HasGetAttributes<T>::value>* = nullptr) {}
336
337 JSONWriter* writer_;
338 };
339};
340
342 const Function& function,
343 uint8_t** compiler_pass_filter /* = nullptr */) {
344 return compiler::PrintFilter::ShouldPrint(function, compiler_pass_filter);
345}
346
347void FlowGraphPrinter::PrintGraph(const char* phase, FlowGraph* flow_graph) {
348 LogBlock lb;
349 if (FLAG_print_flow_graph_as_json) {
350 IlTestPrinter::PrintGraph(phase, flow_graph);
351 } else {
352 THR_Print("*** BEGIN CFG\n%s\n", phase);
353 FlowGraphPrinter printer(*flow_graph);
354 printer.PrintBlocks();
355 THR_Print("*** END CFG\n");
356 }
357 fflush(stdout);
358}
359
360void FlowGraphPrinter::PrintBlock(BlockEntryInstr* block,
361 bool print_locations) {
362 // Print the block entry.
363 PrintOneInstruction(block, print_locations);
364 THR_Print("\n");
365 // And all the successors in the block.
366 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
367 Instruction* current = it.Current();
368
369 // Skip redundant parallel moves.
370 if (!ShouldPrintInstruction(current)) {
371 continue;
372 }
373
374 PrintOneInstruction(current, print_locations);
375 THR_Print("\n");
376 }
377}
378
380 if (!function_.IsNull()) {
381 THR_Print("==== %s (%s", function_.ToFullyQualifiedCString(),
382 Function::KindToCString(function_.kind()));
383 // Output saved arguments descriptor information for dispatchers that
384 // have it, so it's easy to see which dispatcher this graph represents.
385 if (function_.HasSavedArgumentsDescriptor()) {
386 const auto& args_desc_array = Array::Handle(function_.saved_args_desc());
387 const ArgumentsDescriptor args_desc(args_desc_array);
388 THR_Print(", %s", args_desc.ToCString());
389 }
390 THR_Print(")\n");
391 }
392
393 for (intptr_t i = 0; i < block_order_.length(); ++i) {
394 PrintBlock(block_order_[i], print_locations_);
395 }
396}
397
398void FlowGraphPrinter::PrintInstruction(Instruction* instr) {
399 PrintOneInstruction(instr, print_locations_);
400}
401
402void FlowGraphPrinter::PrintOneInstruction(Instruction* instr,
403 bool print_locations) {
404 char str[4000];
405 BufferFormatter f(str, sizeof(str));
407 f.Printf("%3" Pd ": ", FlowGraphAllocator::GetLifetimePosition(instr));
408 }
409 if (!instr->IsBlockEntry()) {
410 f.Printf(" ");
411 }
412 if (auto* const block = instr->AsBlockEntryWithInitialDefs()) {
413 block->PrintBlockHeaderTo(&f);
414 // Output and clear the buffer after each internal definition, as otherwise
415 // too many internal definitions could cause truncation in the output.
416 auto callback = [](BaseTextBuffer* f) {
417 THR_Print("%s", f->buffer());
418 f->Clear();
419 };
420 block->PrintInitialDefinitionsTo(&f, callback);
421 } else {
422 instr->PrintTo(&f);
423 }
424 if (FLAG_print_environments && (instr->env() != nullptr)) {
425 instr->env()->PrintTo(&f);
426 }
427 if (print_locations && (instr->HasLocs())) {
428 instr->locs()->PrintTo(&f);
429 }
430 if (FLAG_trace_inlining_intervals) {
431 f.Printf(" iid: %" Pd "", instr->inlining_id());
432 }
433 THR_Print("%s", f.buffer());
434}
435
436void FlowGraphPrinter::PrintTypeCheck(const ParsedFunction& parsed_function,
437 TokenPosition token_pos,
438 Value* value,
439 const AbstractType& dst_type,
440 const String& dst_name,
441 bool eliminated) {
442 const char* compile_type_name = "unknown";
443 if (value != nullptr && value->reaching_type_ != nullptr) {
444 compile_type_name = value->reaching_type_->ToCString();
445 }
446 THR_Print(
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());
452}
453
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());
459 Function& target = Function::Handle();
460 if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
461 (num_checks_to_print > targets.length())) {
462 num_checks_to_print = targets.length();
463 }
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();
469 if (i > 0) {
470 f->AddString(" | ");
471 }
472 if (range.IsSingleCid()) {
473 const Class& cls = Class::Handle(
474 IsolateGroup::Current()->class_table()->At(range.cid_start));
475 f->Printf("%s", String::Handle(cls.Name()).ToCString());
476 f->Printf(" cid %" Pd " cnt:%" Pd " trgt:'%s'", range.cid_start, count,
477 target.ToQualifiedCString());
478 } else {
479 const Class& cls = Class::Handle(target.Owner());
480 f->Printf("cid %" Pd "-%" Pd " %s", range.cid_start, range.cid_end,
481 String::Handle(cls.Name()).ToCString());
482 f->Printf(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString());
483 }
484
485 if (target_info->exactness.IsTracking()) {
486 f->Printf(" %s", target_info->exactness.ToCString());
487 }
488 }
489 if (num_checks_to_print < targets.length()) {
490 f->AddString("...");
491 }
492 f->AddString("]");
493}
494
495static void PrintCidsHelper(BaseTextBuffer* f,
496 const Cids& targets,
497 intptr_t num_checks_to_print) {
498 f->AddString(" Cids[");
499 f->Printf("%" Pd ": ", targets.length());
500 if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
501 (num_checks_to_print > targets.length())) {
502 num_checks_to_print = targets.length();
503 }
504 for (intptr_t i = 0; i < num_checks_to_print; i++) {
505 const CidRange& range = targets[i];
506 if (i > 0) {
507 f->AddString(" | ");
508 }
509 const Class& cls = Class::Handle(
510 IsolateGroup::Current()->class_table()->At(range.cid_start));
511 f->Printf("%s etc. ", String::Handle(cls.Name()).ToCString());
512 if (range.IsSingleCid()) {
513 f->Printf(" cid %" Pd, range.cid_start);
514 } else {
515 f->Printf(" cid %" Pd "-%" Pd, range.cid_start, range.cid_end);
516 }
517 }
518 if (num_checks_to_print < targets.length()) {
519 f->AddString("...");
520 }
521 f->AddString("]");
522}
523
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()) {
529 f->Printf(
530 "(%s) ",
531 AbstractType::Handle(ic_data.receivers_static_type()).ToCString());
532 }
533 f->Printf("%" Pd ": ", ic_data.NumberOfChecks());
534 Function& target = Function::Handle();
535 if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
536 (num_checks_to_print > ic_data.NumberOfChecks())) {
537 num_checks_to_print = ic_data.NumberOfChecks();
538 }
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);
543 if (i > 0) {
544 f->AddString(" | ");
545 }
546 for (intptr_t k = 0; k < class_ids.length(); k++) {
547 if (k > 0) {
548 f->AddString(", ");
549 }
550 const Class& cls = Class::Handle(
551 IsolateGroup::Current()->class_table()->At(class_ids[k]));
552 f->Printf("%s", String::Handle(cls.Name()).ToCString());
553 }
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());
557 }
558 }
559 if (num_checks_to_print < ic_data.NumberOfChecks()) {
560 f->AddString("...");
561 }
562 f->AddString("]");
563}
564
565static void PrintICDataSortedHelper(BaseTextBuffer* f,
566 const ICData& ic_data_orig) {
567 const ICData& ic_data =
568 ICData::Handle(ic_data_orig.AsUnaryClassChecksSortedByCount());
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);
573 const Class& cls =
574 Class::Handle(IsolateGroup::Current()->class_table()->At(cid));
575 f->Printf("%s : %" Pd ", ", String::Handle(cls.Name()).ToCString(), count);
576 }
577 f->AddString("]");
578}
579
580void FlowGraphPrinter::PrintICData(const ICData& ic_data,
581 intptr_t num_checks_to_print) {
582 char buffer[1024];
583 BufferFormatter f(buffer, sizeof(buffer));
584 PrintICDataHelper(&f, ic_data, num_checks_to_print);
585 THR_Print("%s ", buffer);
586 const Array& a = Array::Handle(ic_data.arguments_descriptor());
587 THR_Print(" arg-desc %" Pd "\n", a.Length());
588}
589
590void FlowGraphPrinter::PrintCidRangeData(const CallTargets& targets,
591 intptr_t num_checks_to_print) {
592 char buffer[1024];
593 BufferFormatter f(buffer, sizeof(buffer));
594 PrintTargetsHelper(&f, targets, num_checks_to_print);
595 THR_Print("%s ", buffer);
596 // TODO(erikcorry): Print args descriptor.
597}
598
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());
604 }
605}
606
607const char* Instruction::ToCString() const {
608 char buffer[1024];
609 BufferFormatter f(buffer, sizeof(buffer));
610 PrintTo(&f);
612}
613
614void Instruction::PrintTo(BaseTextBuffer* f) const {
615 if (GetDeoptId() != DeoptId::kNone) {
616 f->Printf("%s:%" Pd "(", DebugName(), GetDeoptId());
617 } else {
618 f->Printf("%s(", DebugName());
619 }
620 PrintOperandsTo(f);
621 f->AddString(")");
622}
623
624void Instruction::PrintOperandsTo(BaseTextBuffer* f) const {
625 for (int i = 0; i < InputCount(); ++i) {
626 if (i > 0) f->AddString(", ");
627 if (InputAt(i) != nullptr) InputAt(i)->PrintTo(f);
628 }
629}
630
631void Definition::PrintTo(BaseTextBuffer* f) const {
632 PrintUse(f, *this);
633 if (HasSSATemp() || HasTemp()) f->AddString(" <- ");
634 if (GetDeoptId() != DeoptId::kNone) {
635 f->Printf("%s:%" Pd "(", DebugName(), GetDeoptId());
636 } else {
637 f->Printf("%s(", DebugName());
638 }
639 PrintOperandsTo(f);
640 f->AddString(")");
641 if (range_ != nullptr) {
642 f->AddString(" ");
643 range_->PrintTo(f);
644 }
645
646 if (representation() != kNoRepresentation && representation() != kTagged) {
648 } else if (type_ != nullptr) {
649 f->AddString(" ");
650 type_->PrintTo(f);
651 }
652}
653
654void CheckNullInstr::PrintOperandsTo(BaseTextBuffer* f) const {
655 Definition::PrintOperandsTo(f);
656 switch (exception_type()) {
657 case kNoSuchMethod:
658 f->AddString(", NoSuchMethodError");
659 break;
660 case kArgumentError:
661 f->AddString(", ArgumentError");
662 break;
663 case kCastError:
664 f->AddString(", CastError");
665 break;
666 }
667}
668
669void Definition::PrintOperandsTo(BaseTextBuffer* f) const {
670 for (int i = 0; i < InputCount(); ++i) {
671 if (i > 0) f->AddString(", ");
672 if (InputAt(i) != nullptr) {
673 InputAt(i)->PrintTo(f);
674 }
675 }
676}
677
678void RedefinitionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
679 Definition::PrintOperandsTo(f);
680 if (constrained_type_ != nullptr) {
681 f->Printf(" ^ %s", constrained_type_->ToCString());
682 }
683}
684
685void ReachabilityFenceInstr::PrintOperandsTo(BaseTextBuffer* f) const {
686 value()->PrintTo(f);
687}
688
689const char* Value::ToCString() const {
690 char buffer[1024];
691 BufferFormatter f(buffer, sizeof(buffer));
692 PrintTo(&f);
694}
695
696void Value::PrintTo(BaseTextBuffer* f) const {
697 PrintUse(f, *definition());
698
699 if ((reaching_type_ != nullptr) && (reaching_type_ != definition()->type_)) {
700 f->AddString(" ");
701 reaching_type_->PrintTo(f);
702 }
703}
704
705void ConstantInstr::PrintOperandsTo(BaseTextBuffer* f) const {
706 const char* cstr = value().ToCString();
707 const char* new_line = strchr(cstr, '\n');
708 if (new_line == nullptr) {
709 f->Printf("#%s", cstr);
710 } else {
711 const intptr_t pos = new_line - cstr;
712 char* buffer = Thread::Current()->zone()->Alloc<char>(pos + 1);
713 strncpy(buffer, cstr, pos);
714 buffer[pos] = '\0';
715 f->Printf("#%s\\n...", buffer);
716 }
717}
718
719void ConstraintInstr::PrintOperandsTo(BaseTextBuffer* f) const {
720 value()->PrintTo(f);
721 f->AddString(" ^ ");
722 constraint()->PrintTo(f);
723}
724
725void Range::PrintTo(BaseTextBuffer* f) const {
726 f->AddString("[");
727 min_.PrintTo(f);
728 f->AddString(", ");
729 max_.PrintTo(f);
730 f->AddString("]");
731}
732
733const char* Range::ToCString(const Range* range) {
734 if (range == nullptr) return "[_|_, _|_]";
735
736 char buffer[256];
737 BufferFormatter f(buffer, sizeof(buffer));
738 range->PrintTo(&f);
740}
741
742void RangeBoundary::PrintTo(BaseTextBuffer* f) const {
743 switch (kind_) {
744 case kSymbol:
745 f->Printf("v%" Pd "",
746 reinterpret_cast<Definition*>(value_)->ssa_temp_index());
747 if (offset_ != 0) f->Printf("%+" Pd64 "", offset_);
748 break;
749 case kConstant:
750 f->Printf("%" Pd64 "", value_);
751 break;
752 case kUnknown:
753 f->AddString("_|_");
754 break;
755 }
756}
757
758const char* RangeBoundary::ToCString() const {
759 char buffer[256];
760 BufferFormatter f(buffer, sizeof(buffer));
761 PrintTo(&f);
763}
764
765void MakeTempInstr::PrintOperandsTo(BaseTextBuffer* f) const {}
766
767void DropTempsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
768 f->Printf("%" Pd "", num_temps());
769 if (value() != nullptr) {
770 f->AddString(", ");
771 value()->PrintTo(f);
772 }
773}
774
775void AssertAssignableInstr::PrintOperandsTo(BaseTextBuffer* f) const {
776 value()->PrintTo(f);
777 f->AddString(", ");
778 dst_type()->PrintTo(f);
779 f->Printf(", '%s',", dst_name().ToCString());
780 f->AddString(" instantiator_type_args(");
781 instantiator_type_arguments()->PrintTo(f);
782 f->AddString("), function_type_args(");
783 function_type_arguments()->PrintTo(f);
784 f->AddString(")");
785}
786
787void AssertSubtypeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
788 sub_type()->PrintTo(f);
789 f->AddString(", ");
790 super_type()->PrintTo(f);
791 f->AddString(", ");
792 dst_name()->PrintTo(f);
793 f->AddString(", instantiator_type_args(");
794 instantiator_type_arguments()->PrintTo(f);
795 f->AddString("), function_type_args(");
796 function_type_arguments()->PrintTo(f);
797 f->AddString(")");
798}
799
800void AssertBooleanInstr::PrintOperandsTo(BaseTextBuffer* f) const {
801 value()->PrintTo(f);
802}
803
804void ClosureCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
805 if (FLAG_precompiled_mode) {
806 f->AddString(" closure=");
807 } else {
808 f->AddString(" function=");
809 }
810 InputAt(InputCount() - 1)->PrintTo(f);
811 f->Printf("<%" Pd ">", type_args_len());
812 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
813 f->AddString(", ");
814 ArgumentValueAt(i)->PrintTo(f);
815 }
816}
817
818void InstanceCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
819 f->Printf(" %s<%" Pd ">", function_name().ToCString(), type_args_len());
820 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
821 f->AddString(", ");
822 ArgumentValueAt(i)->PrintTo(f);
823 }
824 if (HasICData()) {
825 if (FLAG_display_sorted_ic_data) {
826 PrintICDataSortedHelper(f, *ic_data());
827 } else {
828 PrintICDataHelper(f, *ic_data(), FlowGraphPrinter::kPrintAll);
829 }
830 }
831 if (result_type() != nullptr) {
832 f->Printf(", result_type = %s", result_type()->ToCString());
833 }
834 if (entry_kind() == Code::EntryKind::kUnchecked) {
835 f->AddString(" using unchecked entrypoint");
836 }
837}
838
839void PolymorphicInstanceCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
840 f->Printf(" %s<%" Pd ">", function_name().ToCString(), type_args_len());
841 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
842 f->AddString(", ");
843 ArgumentValueAt(i)->PrintTo(f);
844 }
845 PrintTargetsHelper(f, targets_, FlowGraphPrinter::kPrintAll);
846 if (complete()) {
847 f->AddString(" COMPLETE");
848 }
849 if (entry_kind() == Code::EntryKind::kUnchecked) {
850 f->AddString(" using unchecked entrypoint");
851 }
852}
853
854void DispatchTableCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
855 const String& name =
856 String::Handle(interface_target().QualifiedUserVisibleName());
857 f->AddString(" cid=");
858 class_id()->PrintTo(f);
859 f->Printf(" %s<%" Pd ">", name.ToCString(), type_args_len());
860 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
861 f->AddString(", ");
862 ArgumentValueAt(i)->PrintTo(f);
863 }
864}
865
866void StrictCompareInstr::PrintOperandsTo(BaseTextBuffer* f) const {
867 f->Printf("%s, ", Token::Str(kind()));
868 left()->PrintTo(f);
869 f->AddString(", ");
870 right()->PrintTo(f);
871 if (needs_number_check()) {
872 f->Printf(", with number check");
873 }
874}
875
876void TestCidsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
877 left()->PrintTo(f);
878 f->Printf(" %s [", Token::Str(kind()));
879 intptr_t length = cid_results().length();
880 for (intptr_t i = 0; i < length; i += 2) {
881 f->Printf("0x%" Px ":%s ", cid_results()[i],
882 cid_results()[i + 1] == 0 ? "false" : "true");
883 }
884 f->AddString("] ");
885 if (CanDeoptimize()) {
887 f->AddString("else deoptimize ");
888 } else {
890 f->Printf("else %s ", cid_results()[length - 1] != 0 ? "false" : "true");
891 }
892}
893
894void TestRangeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
895 left()->PrintTo(f);
896 f->Printf(" %s [%" Pd "-%" Pd "]", kind() == Token::kIS ? "in" : "not in",
897 lower_, upper_);
898}
899
900void EqualityCompareInstr::PrintOperandsTo(BaseTextBuffer* f) const {
901 left()->PrintTo(f);
902 f->Printf(" %s ", Token::Str(kind()));
903 right()->PrintTo(f);
904}
905
906void StaticCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
907 f->Printf(" %s<%" Pd "> ", String::Handle(function().name()).ToCString(),
908 type_args_len());
909 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
910 if (i > 0) f->AddString(", ");
911 ArgumentValueAt(i)->PrintTo(f);
912 }
913 if (entry_kind() == Code::EntryKind::kUnchecked) {
914 f->AddString(", using unchecked entrypoint");
915 }
916 if (function().recognized_kind() != MethodRecognizer::kUnknown) {
917 f->Printf(", recognized_kind = %s",
918 MethodRecognizer::KindToCString(function().recognized_kind()));
919 }
920 if (result_type() != nullptr) {
921 f->Printf(", result_type = %s", result_type()->ToCString());
922 }
923}
924
925void CachableIdempotentCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
926 f->Printf(" %s<%" Pd "> ", String::Handle(function().name()).ToCString(),
927 type_args_len());
928 for (intptr_t i = 0; i < ArgumentCount(); ++i) {
929 if (i > 0) f->AddString(", ");
930 ArgumentValueAt(i)->PrintTo(f);
931 }
932}
933
934void LoadLocalInstr::PrintOperandsTo(BaseTextBuffer* f) const {
935 f->Printf("%s @%d", local().name().ToCString(), local().index().value());
936}
937
938void StoreLocalInstr::PrintOperandsTo(BaseTextBuffer* f) const {
939 f->Printf("%s @%d, ", local().name().ToCString(), local().index().value());
940 value()->PrintTo(f);
941}
942
943void NativeCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
944 f->Printf("%s", native_name().ToCString());
945}
946
947void GuardFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
948 f->Printf("%s %s, ", String::Handle(field().name()).ToCString(),
949 field().GuardedPropertiesAsCString());
950 value()->PrintTo(f);
951}
952
953void StoreFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
954 instance()->PrintTo(f);
955 f->Printf(" . %s = ", slot().Name());
956 value()->PrintTo(f);
957 if (slot().representation() != kTagged) {
959 }
960
961 // Here, we just print the value of the enum field. We would prefer to get
962 // the final decision on whether a store barrier will be emitted by calling
963 // ShouldEmitStoreBarrier(), but that can change parts of the flow graph.
964 if (emit_store_barrier_ == kNoStoreBarrier) {
965 f->AddString(", NoStoreBarrier");
966 }
968 f->AddString(", MayStoreInnerPointer");
969 }
970}
971
972void IfThenElseInstr::PrintOperandsTo(BaseTextBuffer* f) const {
973 comparison()->PrintOperandsTo(f);
974 f->Printf(" ? %" Pd " : %" Pd, if_true_, if_false_);
975}
976
977void LoadStaticFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
978 f->Printf("%s", String::Handle(field().name()).ToCString());
979 if (calls_initializer()) {
980 f->AddString(", CallsInitializer");
981 }
982}
983
984void StoreStaticFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
985 f->Printf("%s, ", String::Handle(field().name()).ToCString());
986 value()->PrintTo(f);
987}
988
989void InstanceOfInstr::PrintOperandsTo(BaseTextBuffer* f) const {
990 value()->PrintTo(f);
991 f->Printf(" IS %s,", type().NameCString());
992 f->AddString(" instantiator_type_args(");
993 instantiator_type_arguments()->PrintTo(f);
994 f->AddString("), function_type_args(");
995 function_type_arguments()->PrintTo(f);
996 f->AddString(")");
997}
998
999void RelationalOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1000 f->Printf("%s, ", Token::Str(kind()));
1001 left()->PrintTo(f);
1002 f->AddString(", ");
1003 right()->PrintTo(f);
1004}
1005
1006void AllocationInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1007 Definition::PrintOperandsTo(f);
1008 if (Identity().IsNotAliased()) {
1009 if (InputCount() > 0) {
1010 f->AddString(", ");
1011 }
1012 f->AddString("<not-aliased>");
1013 }
1014}
1015
1016void AllocateObjectInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1017 f->Printf("cls=%s", cls().ScrubbedNameCString());
1018 if (InputCount() > 0 || Identity().IsNotAliased()) {
1019 f->AddString(", ");
1020 }
1021 AllocationInstr::PrintOperandsTo(f);
1022}
1023
1024void MaterializeObjectInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1025 f->Printf("%s", cls_.ScrubbedNameCString());
1026 for (intptr_t i = 0; i < InputCount(); i++) {
1027 f->AddString(", ");
1028 f->Printf("%s: ", slots_[i]->Name());
1029 InputAt(i)->PrintTo(f);
1030 }
1031}
1032
1033void LoadFieldInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1034 instance()->PrintTo(f);
1035 f->Printf(" . %s%s", slot().Name(), IsImmutableLoad() ? " {final}" : "");
1036 if (calls_initializer()) {
1037 f->AddString(", CallsInitializer");
1038 }
1040 f->AddString(", MayLoadInnerPointer");
1041 }
1042}
1043
1044void LoadUntaggedInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1045 object()->PrintTo(f);
1046 f->Printf(", %" Pd, offset());
1047}
1048
1049void CalculateElementAddressInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1050 Definition::PrintOperandsTo(f);
1051 f->Printf(", index_scale=%" Pd "", index_scale());
1052}
1053
1054void InstantiateTypeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1055 const String& type_name = String::Handle(type().Name());
1056 f->Printf("%s,", type_name.ToCString());
1057 f->AddString(" instantiator_type_args(");
1058 instantiator_type_arguments()->PrintTo(f);
1059 f->AddString("), function_type_args(");
1060 function_type_arguments()->PrintTo(f);
1061 f->AddString(")");
1062}
1063
1064void InstantiateTypeArgumentsInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1065 type_arguments()->PrintTo(f);
1066 f->AddString(", instantiator_type_args(");
1067 instantiator_type_arguments()->PrintTo(f);
1068 f->AddString("), function_type_args(");
1069 function_type_arguments()->PrintTo(f);
1070 f->Printf(")");
1071 if (!instantiator_class().IsNull()) {
1072 f->Printf(", instantiator_class(%s)", instantiator_class().ToCString());
1073 }
1074}
1075
1076void AllocateContextInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1077 f->Printf("num_variables=%" Pd "", num_context_variables());
1078 if (InputCount() > 0 || Identity().IsNotAliased()) {
1079 f->AddString(", ");
1080 }
1081 TemplateAllocation::PrintOperandsTo(f);
1082}
1083
1084void AllocateUninitializedContextInstr::PrintOperandsTo(
1085 BaseTextBuffer* f) const {
1086 f->Printf("num_variables=%" Pd "", num_context_variables());
1087 if (InputCount() > 0 || Identity().IsNotAliased()) {
1088 f->AddString(", ");
1089 }
1090 TemplateAllocation::PrintOperandsTo(f);
1091}
1092
1093void TruncDivModInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1094 Definition::PrintOperandsTo(f);
1095}
1096
1097void ExtractNthOutputInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1098 f->Printf("Extract %" Pd " from ", index());
1099 Definition::PrintOperandsTo(f);
1100}
1101
1102void UnboxLaneInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1103 Definition::PrintOperandsTo(f);
1104 f->Printf(", lane %" Pd, lane());
1105}
1106
1107void BoxLanesInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1108 Definition::PrintOperandsTo(f);
1109}
1110
1111void UnaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1112 f->Printf("%s, ", Token::Str(op_kind()));
1113 value()->PrintTo(f);
1114}
1115
1116void BinaryIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1117 f->Printf("%s", Token::Str(op_kind()));
1118 if (is_truncating()) {
1119 f->AddString(" [tr]");
1120 } else if (!can_overflow()) {
1121 f->AddString(" [-o]");
1122 }
1123 f->AddString(", ");
1124 left()->PrintTo(f);
1125 f->AddString(", ");
1126 right()->PrintTo(f);
1127}
1128
1129void BinaryDoubleOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1130 f->Printf("%s, ", Token::Str(op_kind()));
1131 left()->PrintTo(f);
1132 f->AddString(", ");
1133 right()->PrintTo(f);
1134}
1135
1136void DoubleTestOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1137 switch (op_kind()) {
1138 case MethodRecognizer::kDouble_getIsNaN:
1139 f->AddString("IsNaN ");
1140 break;
1141 case MethodRecognizer::kDouble_getIsInfinite:
1142 f->AddString("IsInfinite ");
1143 break;
1144 case MethodRecognizer::kDouble_getIsNegative:
1145 f->AddString("IsNegative ");
1146 break;
1147 default:
1148 UNREACHABLE();
1149 }
1150 value()->PrintTo(f);
1151}
1152
1153static const char* const simd_op_kind_string[] = {
1154#define CASE(Arity, Mask, Name, ...) #Name,
1156#undef CASE
1157};
1158
1159void SimdOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1160 f->Printf("%s", simd_op_kind_string[kind()]);
1161 if (HasMask()) {
1162 f->Printf(", mask = %" Pd "", mask());
1163 }
1164 for (intptr_t i = 0; i < InputCount(); i++) {
1165 f->AddString(", ");
1166 InputAt(i)->PrintTo(f);
1167 }
1168}
1169
1170void UnaryDoubleOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1171 f->Printf("%s, ", Token::Str(op_kind()));
1172 value()->PrintTo(f);
1173}
1174
1175void LoadClassIdInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1176 if (!input_can_be_smi_) {
1177 f->AddString("<non-smi> ");
1178 }
1179 object()->PrintTo(f);
1180}
1181
1182void CheckClassIdInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1183 value()->PrintTo(f);
1184
1185 const Class& cls = Class::Handle(
1186 IsolateGroup::Current()->class_table()->At(cids().cid_start));
1187 const String& name = String::Handle(cls.ScrubbedName());
1188 if (cids().IsSingleCid()) {
1189 f->Printf(", %s", name.ToCString());
1190 } else {
1191 const Class& cls2 = Class::Handle(
1192 IsolateGroup::Current()->class_table()->At(cids().cid_end));
1193 const String& name2 = String::Handle(cls2.ScrubbedName());
1194 f->Printf(", cid %" Pd "-%" Pd " %s-%s", cids().cid_start, cids().cid_end,
1195 name.ToCString(), name2.ToCString());
1196 }
1197}
1198
1199void HashIntegerOpInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1200 if (smi_) {
1201 f->AddString("smi ");
1202 }
1203
1204 value()->PrintTo(f);
1205}
1206
1207void CheckClassInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1208 value()->PrintTo(f);
1209 PrintCidsHelper(f, cids_, FlowGraphPrinter::kPrintAll);
1210 if (IsNullCheck()) {
1211 f->AddString(" nullcheck");
1212 }
1213}
1214
1215void CheckConditionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1216 comparison()->PrintOperandsTo(f);
1217}
1218
1219void InvokeMathCFunctionInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1220 f->Printf("%s, ", MethodRecognizer::KindToCString(recognized_kind_));
1221 Definition::PrintOperandsTo(f);
1222}
1223
1224void GraphEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
1225 f->Printf("B%" Pd "[graph]:%" Pd, block_id(), GetDeoptId());
1226}
1227
1228void JoinEntryInstr::PrintTo(BaseTextBuffer* f) const {
1229 if (try_index() != kInvalidTryIndex) {
1230 f->Printf("B%" Pd "[join try_idx %" Pd "]:%" Pd " pred(", block_id(),
1231 try_index(), GetDeoptId());
1232 } else {
1233 f->Printf("B%" Pd "[join]:%" Pd " pred(", block_id(), GetDeoptId());
1234 }
1235 for (intptr_t i = 0; i < predecessors_.length(); ++i) {
1236 if (i > 0) f->AddString(", ");
1237 f->Printf("B%" Pd, predecessors_[i]->block_id());
1238 }
1239 f->AddString(")");
1240 if (phis_ != nullptr) {
1241 f->AddString(" {");
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);
1246 }
1247 f->AddString("\n}");
1248 }
1249 if (HasParallelMove()) {
1250 f->AddString(" ");
1251 parallel_move()->PrintTo(f);
1252 }
1253}
1254
1255void IndirectEntryInstr::PrintTo(BaseTextBuffer* f) const {
1256 f->Printf("B%" Pd "[join indirect", block_id());
1257 if (try_index() != kInvalidTryIndex) {
1258 f->Printf(" try_idx %" Pd, try_index());
1259 }
1260 f->Printf("]:%" Pd " pred(", GetDeoptId());
1261 for (intptr_t i = 0; i < predecessors_.length(); ++i) {
1262 if (i > 0) f->AddString(", ");
1263 f->Printf("B%" Pd, predecessors_[i]->block_id());
1264 }
1265 f->AddString(")");
1266 if (phis_ != nullptr) {
1267 f->AddString(" {");
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);
1272 }
1273 f->AddString("\n}");
1274 }
1275 if (HasParallelMove()) {
1276 f->AddString(" ");
1277 parallel_move()->PrintTo(f);
1278 }
1279}
1280
1281void PhiInstr::PrintTo(BaseTextBuffer* f) const {
1282 f->Printf("v%" Pd " <- phi(", ssa_temp_index());
1283 for (intptr_t i = 0; i < inputs_.length(); ++i) {
1284 if (inputs_[i] != nullptr) inputs_[i]->PrintTo(f);
1285 if (i < inputs_.length() - 1) f->AddString(", ");
1286 }
1287 f->AddString(")");
1288 f->AddString(is_alive() ? " alive" : " dead");
1289 if (range_ != nullptr) {
1290 f->AddString(" ");
1291 range_->PrintTo(f);
1292 }
1293
1294 if (representation() != kNoRepresentation && representation() != kTagged) {
1296 }
1297
1298 if (HasType()) {
1299 f->Printf(" %s", TypeAsCString());
1300 }
1301}
1302
1303void UnboxIntegerInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1304 if (is_truncating()) {
1305 f->AddString("[tr], ");
1306 }
1308 f->AddString("[guard-inputs], ");
1309 } else {
1310 f->AddString("[non-speculative], ");
1311 }
1312 Definition::PrintOperandsTo(f);
1313}
1314
1315void IntConverterInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1316 f->Printf("%s->%s%s, ", RepresentationUtils::ToCString(from()),
1318 is_truncating() ? "[tr]" : "");
1319 Definition::PrintOperandsTo(f);
1320}
1321
1322void BitCastInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1323 Definition::PrintOperandsTo(f);
1324 f->Printf(" (%s -> %s)", RepresentationUtils::ToCString(from()),
1326}
1327
1328void ParameterInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1329 f->Printf("%" Pd " @%s", env_index(), location().ToCString());
1330}
1331
1332void CheckStackOverflowInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1333 f->Printf("stack=%" Pd ", loop=%" Pd, stack_depth(), loop_depth());
1334}
1335
1336void TargetEntryInstr::PrintTo(BaseTextBuffer* f) const {
1337 if (try_index() != kInvalidTryIndex) {
1338 f->Printf("B%" Pd "[target try_idx %" Pd "]:%" Pd, block_id(), try_index(),
1339 GetDeoptId());
1340 } else {
1341 f->Printf("B%" Pd "[target]:%" Pd, block_id(), GetDeoptId());
1342 }
1343 if (HasParallelMove()) {
1344 f->AddString(" ");
1345 parallel_move()->PrintTo(f);
1346 }
1347}
1348
1349void BlockEntryWithInitialDefs::PrintTo(BaseTextBuffer* f) const {
1351 PrintInitialDefinitionsTo(f, [](BaseTextBuffer* f) {});
1352}
1353
1355 BaseTextBuffer* f,
1356 std::function<void(BaseTextBuffer* f)> callback) const {
1357 const GrowableArray<Definition*>& defns = initial_definitions_;
1358 if (defns.length() > 0) {
1359 f->AddString(" {");
1360 for (intptr_t i = 0; i < defns.length(); ++i) {
1361 Definition* const def = defns[i];
1362 // Skip constants which are not used in the graph.
1363 if (!ShouldPrintInstruction(def)) {
1364 continue;
1365 }
1366 f->AddString("\n ");
1367 def->PrintTo(f);
1368 callback(f);
1369 }
1370 f->AddString("\n}");
1371 }
1372}
1373
1374void OsrEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
1375 f->Printf("B%" Pd "[osr entry]:%" Pd " stack_depth=%" Pd, block_id(),
1376 GetDeoptId(), stack_depth());
1377 if (HasParallelMove()) {
1378 f->AddString("\n");
1379 parallel_move()->PrintTo(f);
1380 }
1381}
1382
1383void FunctionEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
1384 f->Printf("B%" Pd "[function entry]:%" Pd, block_id(), GetDeoptId());
1385 if (HasParallelMove()) {
1386 f->AddString("\n");
1387 parallel_move()->PrintTo(f);
1388 }
1389}
1390
1391void NativeEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
1392 f->Printf("B%" Pd "[native function entry]:%" Pd, block_id(), GetDeoptId());
1393 if (HasParallelMove()) {
1394 f->AddString("\n");
1395 parallel_move()->PrintTo(f);
1396 }
1397}
1398
1399void FfiCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1400 f->AddString(" pointer=");
1401 InputAt(TargetAddressIndex())->PrintTo(f);
1402 if (marshaller_.ReturnsCompound()) {
1403 f->AddString(", compound_return_typed_data=");
1405 }
1406 intptr_t def_index = 0;
1407 for (intptr_t arg_index = 0; arg_index < marshaller_.num_args();
1408 arg_index++) {
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);
1412 f->AddString(", ");
1413 if (is_compound) f->AddString("(");
1414 for (intptr_t i = 0; i < num_defs; i++) {
1415 InputAt(def_index)->PrintTo(f);
1416 if ((i + 1) < num_defs) f->AddString(", ");
1417 def_index++;
1418 }
1419 if (is_compound) f->AddString(")");
1420 f->AddString(" (@");
1421 arg_location.PrintTo(f);
1422 f->AddString(")");
1423 }
1424}
1425
1426void LeafRuntimeCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1427 f->AddString("target_address=");
1428 InputAt(TargetAddressIndex())->PrintTo(f);
1429 for (intptr_t i = 0, n = argument_representations_.length(); i < n; ++i) {
1430 f->AddString(", ");
1431 InputAt(i)->PrintTo(f);
1432 }
1433}
1434
1435void NativeReturnInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1436 if (marshaller_.NumReturnDefinitions() == 1) {
1437 InputAt(0)->PrintTo(f);
1438 } else {
1439 ASSERT_EQUAL(marshaller_.NumReturnDefinitions(), 2);
1440 f->AddString("(");
1441 InputAt(0)->PrintTo(f);
1442 f->AddString(", ");
1443 InputAt(1)->PrintTo(f);
1444 f->AddString(")");
1445 }
1446
1447 f->AddString(" (@");
1448 marshaller_.Location(compiler::ffi::kResultIndex).PrintTo(f);
1449 f->AddString(")");
1450}
1451
1452void NativeParameterInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1453 // Where the calling convention puts it.
1454 marshaller_.Location(marshaller_.ArgumentIndex(def_index_)).PrintTo(f);
1455 f->AddString(" at ");
1456 // Where the arguments are when pushed on the stack.
1457 marshaller_.NativeLocationOfNativeParameter(def_index_).PrintTo(f);
1458}
1459
1460void CatchBlockEntryInstr::PrintBlockHeaderTo(BaseTextBuffer* f) const {
1461 f->Printf("B%" Pd "[target catch try_idx %" Pd " catch_try_idx %" Pd "]",
1463 if (HasParallelMove()) {
1464 f->AddString("\n");
1465 parallel_move()->PrintTo(f);
1466 }
1467}
1468
1469void LoadIndexedUnsafeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1470 f->Printf("%s[", RegisterNames::RegisterName(base_reg()));
1471 index()->PrintTo(f);
1472 f->Printf(" + %" Pd "]", offset());
1473}
1474
1475void StoreIndexedUnsafeInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1476 f->Printf("%s[", RegisterNames::RegisterName(base_reg()));
1477 index()->PrintTo(f);
1478 f->Printf(" + %" Pd "], ", offset());
1479 value()->PrintTo(f);
1480}
1481
1482void LoadIndexedInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1483 auto& cls =
1484 Class::Handle(IsolateGroup::Current()->class_table()->At(class_id()));
1485 if (!cls.IsNull()) {
1486 f->Printf("[%s] ", cls.ScrubbedNameCString());
1487 } else {
1488 f->Printf("[cid %" Pd "] ", class_id());
1489 }
1490 Instruction::PrintOperandsTo(f);
1491}
1492
1493void StoreIndexedInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1494 auto& cls =
1495 Class::Handle(IsolateGroup::Current()->class_table()->At(class_id()));
1496 if (!cls.IsNull()) {
1497 f->Printf("[%s] ", cls.ScrubbedNameCString());
1498 } else {
1499 f->Printf("[cid %" Pd "] ", class_id());
1500 }
1501 Instruction::PrintOperandsTo(f);
1502 if (!ShouldEmitStoreBarrier()) {
1503 f->AddString(", NoStoreBarrier");
1504 }
1505}
1506
1507void MemoryCopyInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1508 Instruction::PrintOperandsTo(f);
1509 auto& cls =
1510 Class::Handle(IsolateGroup::Current()->class_table()->At(dest_cid_));
1511 if (!cls.IsNull()) {
1512 f->Printf(", dest_cid=%s (%d)", cls.ScrubbedNameCString(), dest_cid_);
1513 } else {
1514 f->Printf(", dest_cid=%d", dest_cid_);
1515 }
1516 if (dest()->definition()->representation() == kUntagged) {
1517 f->Printf(" [untagged]");
1518 }
1519 cls = IsolateGroup::Current()->class_table()->At(src_cid_);
1520 if (!cls.IsNull()) {
1521 f->Printf(", src_cid=%s (%d)", cls.ScrubbedNameCString(), src_cid_);
1522 } else {
1523 f->Printf(", src_cid=%d", src_cid_);
1524 }
1525 if (src()->definition()->representation() == kUntagged) {
1526 f->Printf(" [untagged]");
1527 }
1528 if (element_size() != 1) {
1529 f->Printf(", element_size=%" Pd "", element_size());
1530 }
1531 if (unboxed_inputs()) {
1532 f->AddString(", unboxed_inputs");
1533 }
1534 if (can_overlap()) {
1535 f->AddString(", can_overlap");
1536 }
1537}
1538
1539void TailCallInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1540 const char* name = "<unknown code>";
1541 if (code_.IsStubCode()) {
1542 name = StubCode::NameOfStub(code_.EntryPoint());
1543 } else {
1544 const Object& owner = Object::Handle(code_.owner());
1545 if (owner.IsFunction()) {
1547 .ToFullyQualifiedCString();
1548 }
1549 }
1550 f->Printf("%s(", name);
1551 InputAt(0)->PrintTo(f);
1552 f->AddString(")");
1553}
1554
1555void Call1ArgStubInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1556 const char* name = "";
1557 switch (stub_id_) {
1559 name = "CloneSuspendState";
1560 break;
1561 case StubId::kInitAsync:
1562 name = "InitAsync";
1563 break;
1565 name = "InitAsyncStar";
1566 break;
1568 name = "InitSyncStar";
1569 break;
1571 name = "FfiAsyncCallbackSend";
1572 break;
1573 }
1574 f->Printf("%s(", name);
1575 operand()->PrintTo(f);
1576 f->AddString(")");
1577}
1578
1579void SuspendInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1580 const char* name = "";
1581 switch (stub_id_) {
1582 case StubId::kAwait:
1583 name = "Await";
1584 break;
1586 name = "AwaitWithTypeCheck";
1587 break;
1589 name = "YieldAsyncStar";
1590 break;
1592 name = "SuspendSyncStarAtStart";
1593 break;
1595 name = "SuspendSyncStarAtYield";
1596 break;
1597 }
1598 f->Printf("%s(", name);
1599 Definition::PrintOperandsTo(f);
1600 f->AddString(")");
1601}
1602
1603void MoveArgumentInstr::PrintOperandsTo(BaseTextBuffer* f) const {
1604 f->Printf("%s <- ", location().ToCString());
1605 value()->PrintTo(f);
1606}
1607
1608void GotoInstr::PrintTo(BaseTextBuffer* f) const {
1609 if (HasParallelMove()) {
1610 parallel_move()->PrintTo(f);
1611 f->AddString(" ");
1612 }
1613 if (GetDeoptId() != DeoptId::kNone) {
1614 f->Printf("goto:%" Pd " B%" Pd "", GetDeoptId(), successor()->block_id());
1615 } else {
1616 f->Printf("goto: B%" Pd "", successor()->block_id());
1617 }
1618}
1619
1620void IndirectGotoInstr::PrintTo(BaseTextBuffer* f) const {
1621 if (GetDeoptId() != DeoptId::kNone) {
1622 f->Printf("igoto:%" Pd "(", GetDeoptId());
1623 } else {
1624 f->AddString("igoto:(");
1625 }
1626 InputAt(0)->PrintTo(f);
1627 f->AddString(")");
1628}
1629
1630void BranchInstr::PrintTo(BaseTextBuffer* f) const {
1631 f->Printf("%s ", DebugName());
1632 f->AddString("if ");
1633 comparison()->PrintTo(f);
1634
1635 f->Printf(" goto (%" Pd ", %" Pd ")", true_successor()->block_id(),
1636 false_successor()->block_id());
1637}
1638
1639void ParallelMoveInstr::PrintTo(BaseTextBuffer* f) const {
1640 f->Printf("%s ", DebugName());
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);
1646 }
1647}
1648
1649void Utf8ScanInstr::PrintTo(BaseTextBuffer* f) const {
1651 f->Printf(" [%s]", scan_flags_field_.Name());
1652}
1653
1654void Environment::PrintTo(BaseTextBuffer* f) const {
1655 f->AddString(" env={ ");
1656 int arg_count = 0;
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++);
1661 } else {
1662 values_[i]->PrintTo(f);
1663 }
1664 if ((locations_ != nullptr) && !locations_[i].IsInvalid()) {
1665 f->AddString(" [");
1666 locations_[i].PrintTo(f);
1667 f->AddString("]");
1668 }
1669 }
1670 f->AddString(" }");
1671 if (outer_ != nullptr) outer_->PrintTo(f);
1672}
1673
1674const char* Environment::ToCString() const {
1675 char buffer[1024];
1676 BufferFormatter bf(buffer, 1024);
1677 PrintTo(&bf);
1679}
1680
1681#else // defined(INCLUDE_IL_PRINTER)
1682
1683const char* Instruction::ToCString() const {
1684 return DebugName();
1685}
1686
1688 bool print_locations) {
1689 UNREACHABLE();
1690}
1691
1693 TokenPosition token_pos,
1694 Value* value,
1695 const AbstractType& dst_type,
1696 const String& dst_name,
1697 bool eliminated) {
1698 UNREACHABLE();
1699}
1700
1702 bool print_locations) {
1703 UNREACHABLE();
1704}
1705
1706void FlowGraphPrinter::PrintGraph(const char* phase, FlowGraph* flow_graph) {
1707 UNREACHABLE();
1708}
1709
1711 intptr_t num_checks_to_print) {
1712 UNREACHABLE();
1713}
1714
1716 const Function& function,
1717 uint8_t** compiler_pass_filter /* = nullptr */) {
1718 return false;
1719}
1720
1721#endif // defined(INCLUDE_IL_PRINTER)
1722
1723} // namespace dart
#define test(name)
int count
Definition: FontMgrTest.cpp:50
SkPoint pos
static int block_count(const SkSBlockAllocator< N > &pool)
static bool apply(Pass *pass, SkRecord *record)
#define UNREACHABLE()
Definition: assert.h:248
#define ASSERT_EQUAL(expected, actual)
Definition: assert.h:309
intptr_t num_context_variables() const
Definition: il.h:8392
const Class & cls() const
Definition: il.h:7435
virtual intptr_t InputCount() const
Definition: il.h:7438
intptr_t num_context_variables() const
Definition: il.h:7594
virtual AliasIdentity Identity() const
Definition: il.h:7322
Value * dst_type() const
Definition: il.h:4423
const String & dst_name() const
Definition: il.h:4430
Value * value() const
Definition: il.h:4422
Value * function_type_arguments() const
Definition: il.h:4427
Value * instantiator_type_arguments() const
Definition: il.h:4424
Value * value() const
Definition: il.h:4491
Value * function_type_arguments() const
Definition: il.h:4340
Value * dst_name() const
Definition: il.h:4343
Value * super_type() const
Definition: il.h:4342
Value * sub_type() const
Definition: il.h:4341
Value * instantiator_type_arguments() const
Definition: il.h:4337
intptr_t length() const
Token::Kind op_kind() const
Definition: il.h:9038
Value * right() const
Definition: il.h:9036
Value * left() const
Definition: il.h:9035
bool can_overflow() const
Definition: il.h:9400
Value * right() const
Definition: il.h:9398
Token::Kind op_kind() const
Definition: il.h:9396
Value * left() const
Definition: il.h:9397
bool is_truncating() const
Definition: il.h:9406
Representation to() const
Definition: il.h:11121
Representation from() const
Definition: il.h:11120
intptr_t try_index() const
Definition: il.h:1730
ParallelMoveInstr * parallel_move() const
Definition: il.h:1689
bool HasParallelMove() const
Definition: il.h:1691
intptr_t block_id() const
Definition: il.h:1661
intptr_t stack_depth() const
Definition: il.h:1756
void PrintInitialDefinitionsTo(BaseTextBuffer *f, std::function< void(BaseTextBuffer *f)> callback) const
virtual void PrintBlockHeaderTo(BaseTextBuffer *f) const
Definition: il.h:1936
TargetEntryInstr * false_successor() const
Definition: il.h:4048
TargetEntryInstr * true_successor() const
Definition: il.h:4047
ComparisonInstr * comparison() const
Definition: il.h:4021
const Function & function() const
Definition: il.h:5746
intptr_t index_scale() const
Definition: il.h:8015
Value * operand() const
Definition: il.h:11448
intptr_t catch_try_index() const
Definition: il.h:2381
const CidRangeValue & cids() const
Definition: il.h:10756
Value * value() const
Definition: il.h:10755
Value * value() const
Definition: il.h:10594
bool IsNullCheck() const
Definition: il.h:10600
ComparisonInstr * comparison() const
Definition: il.h:10974
ExceptionType exception_type() const
Definition: il.h:10704
intptr_t stack_depth() const
Definition: il.h:9905
intptr_t loop_depth() const
Definition: il.h:9906
ClassPtr At(intptr_t cid) const
Definition: class_table.h:362
void PrintTo(BaseTextBuffer *f) const
const Object & value() const
Definition: il.h:4230
Value * value() const
Definition: il.h:4192
Range * constraint() const
Definition: il.h:4193
bool HasTemp() const
Definition: il.h:2501
bool HasSSATemp() const
Definition: il.h:2508
Range * range_
Definition: il.h:2692
intptr_t ssa_temp_index() const
Definition: il.h:2503
bool HasType() const
Definition: il.h:2530
static constexpr intptr_t kNone
Definition: deopt_id.h:27
Value * class_id() const
Definition: il.h:5062
const Function & interface_target() const
Definition: il.h:5056
Value * value() const
Definition: il.h:9101
MethodRecognizer::Kind op_kind() const
Definition: il.h:9103
Value * value() const
Definition: il.h:5861
intptr_t num_temps() const
Definition: il.h:5863
void PrintTo(BaseTextBuffer *f) const
const char * ToCString() const
intptr_t index() const
Definition: il.h:10335
intptr_t CompoundReturnTypedDataIndex() const
Definition: il.h:6105
intptr_t TargetAddressIndex() const
Definition: il.h:6100
static DART_FORCE_INLINE bool HasLifetimePosition(Instruction *instr)
Definition: linearscan.h:74
static DART_FORCE_INLINE intptr_t GetLifetimePosition(const Instruction *instr)
Definition: linearscan.h:78
static void PrintOneInstruction(Instruction *instr, bool print_locations)
Definition: il_printer.cc:1687
static void PrintGraph(const char *phase, FlowGraph *flow_graph)
Definition: il_printer.cc:1706
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)
Definition: il_printer.cc:1715
static void PrintBlock(BlockEntryInstr *block, bool print_locations)
Definition: il_printer.cc:1701
static constexpr intptr_t kPrintAll
Definition: il_printer.h:23
FlowGraphPrinter(const FlowGraph &flow_graph, bool print_locations=false)
Definition: il_printer.h:25
void PrintInstruction(Instruction *instr)
static void PrintICData(const ICData &ic_data, intptr_t num_checks_to_print=kPrintAll)
Definition: il_printer.cc:1710
static void PrintTypeCheck(const ParsedFunction &parsed_function, TokenPosition token_pos, Value *value, const AbstractType &dst_type, const String &dst_name, bool eliminated)
Definition: il_printer.cc:1692
const char * ToFullyQualifiedCString() const
Definition: object.cc:9762
static const char * KindToCString(UntaggedFunction::Kind kind)
Definition: object.cc:8419
bool HasSavedArgumentsDescriptor() const
Definition: object.h:3273
UntaggedFunction::Kind kind() const
Definition: object.h:3349
ArrayPtr saved_args_desc() const
Definition: object.cc:8133
ParallelMoveInstr * parallel_move() const
Definition: il.h:3735
bool HasParallelMove() const
Definition: il.h:3737
JoinEntryInstr * successor() const
Definition: il.h:3713
const Field & field() const
Definition: il.h:6520
Value * value() const
Definition: il.h:6518
Value * value() const
Definition: il.h:9189
ComparisonInstr * comparison() const
Definition: il.h:5483
CompileType * result_type() const
Definition: il.h:4748
Code::EntryKind entry_kind() const
Definition: il.h:4759
const ICData * ic_data() const
Definition: il.h:4716
bool HasICData() const
Definition: il.h:4717
const String & function_name() const
Definition: il.h:4724
const AbstractType & type() const
Definition: il.h:7284
Value * function_type_arguments() const
Definition: il.h:7282
Value * instantiator_type_arguments() const
Definition: il.h:7281
Value * value() const
Definition: il.h:7280
Value * type_arguments() const
Definition: il.h:8308
Value * instantiator_type_arguments() const
Definition: il.h:8306
Value * function_type_arguments() const
Definition: il.h:8307
const Class & instantiator_class() const
Definition: il.h:8309
Value * function_type_arguments() const
Definition: il.h:8255
const AbstractType & type() const
Definition: il.h:8256
Value * instantiator_type_arguments() const
Definition: il.h:8254
virtual intptr_t InputCount() const =0
intptr_t GetDeoptId() const
Definition: il.h:1409
virtual Value * InputAt(intptr_t i) const =0
@ kGuardInputs
Definition: il.h:972
const char * ToCString() const
Definition: il_printer.cc:1683
virtual Representation representation() const
Definition: il.h:1260
bool CanDeoptimize() const
Definition: il.h:1079
Value * ArgumentValueAt(intptr_t index) const
Definition: il.h:3435
intptr_t deopt_id() const
Definition: il.h:993
SpeculativeMode SpeculativeModeOfInputs() const
Definition: il.h:1245
virtual const char * DebugName() const =0
bool is_truncating() const
Definition: il.h:11048
Representation to() const
Definition: il.h:11047
Representation from() const
Definition: il.h:11046
static IsolateGroup * Current()
Definition: isolate.h:539
ClassTable * class_table() const
Definition: isolate.h:496
GrowableArray< BlockEntryInstr * > predecessors_
Definition: il.h:2107
intptr_t TargetAddressIndex() const
Definition: il.h:6198
Value * object() const
Definition: il.h:8066
const Slot & slot() const
Definition: il.h:8144
bool IsImmutableLoad() const
Definition: il.h:8177
InnerPointerAccess loads_inner_pointer() const
Definition: il.h:8146
Value * instance() const
Definition: il.h:8143
intptr_t class_id() const
Definition: il.h:6803
Value * index() const
Definition: il.h:3127
intptr_t offset() const
Definition: il.h:3129
Register base_reg() const
Definition: il.h:3128
const LocalVariable & local() const
Definition: il.h:5814
const Field & field() const
Definition: il.h:6683
Value * object() const
Definition: il.h:7945
intptr_t offset() const
Definition: il.h:7946
void PrintTo(BaseTextBuffer *f) const
Definition: locations.cc:420
bool unboxed_inputs() const
Definition: il.h:3216
Value * dest() const
Definition: il.h:3208
intptr_t element_size() const
Definition: il.h:3215
bool can_overlap() const
Definition: il.h:3217
Value * src() const
Definition: il.h:3207
static const char * KindToCString(Kind kind)
Value * value() const
Definition: il.h:3377
Location location() const
Definition: il.h:3374
const String & native_name() const
Definition: il.h:6022
virtual Value * InputAt(intptr_t i) const
Definition: il.h:3580
virtual const char * ToCString() const
Definition: object.h:366
bool IsNull() const
Definition: object.h:363
static Object & Handle()
Definition: object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition: object.h:325
const Location & location() const
Definition: il.h:2946
bool is_alive() const
Definition: il.h:2827
virtual Representation representation() const
Definition: il.h:2835
const char * ToCString() const
void PrintTo(BaseTextBuffer *f) const
static const char * ToCString(const Range *range)
void PrintTo(BaseTextBuffer *f) const
Value * value() const
Definition: il.h:4156
static const char * RegisterName(Register reg)
Definition: constants.h:46
intptr_t mask() const
Definition: il.h:11359
virtual intptr_t InputCount() const
Definition: il.cc:8448
virtual Value * InputAt(intptr_t i) const
Definition: il.h:11353
Kind kind() const
Definition: il.h:11358
CompileType * result_type() const
Definition: il.h:5652
const Function & function() const
Definition: il.h:5623
Code::EntryKind entry_kind() const
Definition: il.h:5666
InnerPointerAccess stores_inner_pointer() const
Definition: il.h:6450
Value * value() const
Definition: il.h:6424
Value * instance() const
Definition: il.h:6422
const Slot & slot() const
Definition: il.h:6423
bool ShouldEmitStoreBarrier() const
Definition: il.h:7089
intptr_t class_id() const
Definition: il.h:7086
intptr_t offset() const
Definition: il.h:3074
Value * value() const
Definition: il.h:3072
Register base_reg() const
Definition: il.h:3073
Value * index() const
Definition: il.h:3071
Value * value() const
Definition: il.h:5963
const LocalVariable & local() const
Definition: il.h:5962
const Field & field() const
Definition: il.h:6729
Value * value() const
Definition: il.h:6730
bool needs_number_check() const
Definition: il.h:5125
static const char * NameOfStub(uword entry_point)
Definition: stub_code.cc:330
virtual intptr_t InputCount() const
Definition: il.h:7389
intptr_t type_args_len() const
Definition: il.h:4614
intptr_t ArgumentCount() const
Definition: il.h:4586
virtual Value * InputAt(intptr_t i) const
Definition: il.h:1515
bool calls_initializer() const
Definition: il.h:6623
const ZoneGrowableArray< intptr_t > & cid_results() const
Definition: il.h:5234
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
static const char * Str(Kind tok)
Definition: token.h:269
Value * value() const
Definition: il.h:9828
Token::Kind op_kind() const
Definition: il.h:9829
Value * value() const
Definition: il.h:9240
Token::Kind op_kind() const
Definition: il.h:9241
bool is_truncating() const
Definition: il.h:8772
intptr_t lane() const
Definition: il.h:10416
Definition: il.h:75
Definition * definition() const
Definition: il.h:103
const char * ToCString() const
InputsArray inputs_
Definition: il.h:2800
intptr_t InputCount() const
Definition: il.h:2794
Value * InputAt(intptr_t i) const
Definition: il.h:2795
char * PrintToString(const char *format,...) PRINTF_ATTRIBUTE(2
Definition: zone.cc:313
char * MakeCopyOfString(const char *str)
Definition: zone.cc:270
ElementType * Alloc(intptr_t length)
#define THR_Print(format,...)
Definition: log.h:20
#define ASSERT(E)
struct MyStruct a[10]
glong glong end
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
uint8_t value
void PrintTo(FlValue *v, std::ostream *os)
Definition: fl_test.cc:78
uint32_t * target
Dart_NativeFunction function
Definition: fuchsia.cc:51
#define CASE(Arity, Mask, Name, Args, Result)
#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs)
Definition: il.h:11827
#define FOR_EACH_INSTRUCTION(M)
Definition: il.h:405
#define SIMD_OP_LIST(M, BINARY_OP)
Definition: il.h:11249
size_t length
ImplicitString Name
Definition: DMSrcSink.h:38
const intptr_t kResultIndex
Definition: marshaller.h:28
Definition: dart_vm.cc:33
const char *const name
DART_EXPORT bool IsNull(Dart_Handle object)
@ kNoStoreBarrier
Definition: il.h:6301
Representation
Definition: locations.h:66
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")
const intptr_t cid
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
Definition: switches.h:126
#define Px
Definition: globals.h:410
#define Pd64
Definition: globals.h:416
#define Pd
Definition: globals.h:408
#define T
Definition: precompiler.cc:65
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741
static const char * ToCString(Representation rep)
Definition: locations.cc:129