19#if !defined(DART_PRECOMPILED_RUNTIME)
30 klass_(
Class::Handle()),
32 string_(
String::Handle()) {}
44 buffer->AddString(
"TypeTestingStub_");
52 const intptr_t
cid = Type::Cast(
type).type_class_id();
54 klass_ = class_table->
At(
cid);
62 buffer->Printf(
"nolib%" Pd "_", nonce_++);
69 if (!type_arguments.IsNull()) {
70 for (intptr_t
i = 0, n = type_arguments.Length();
i < n; ++
i) {
71 type_ = type_arguments.TypeAt(
i);
73 StringifyTypeTo(
buffer, type_);
76 }
else if (
type.IsTypeParameter()) {
77 buffer->AddString(TypeParameter::Cast(
type).CanonicalNameCString());
78 }
else if (
type.IsRecordType()) {
79 const RecordType& rec = RecordType::Cast(
type);
80 buffer->AddString(
"Record");
81 const intptr_t num_fields = rec.NumFields();
82 const auto& field_names =
84 const intptr_t num_positional_fields = num_fields - field_names.Length();
86 for (intptr_t
i = 0;
i < num_fields; ++
i) {
88 type_ ^= field_types.At(
i);
89 StringifyTypeTo(
buffer, type_);
90 if (
i >= num_positional_fields) {
92 string_ ^= field_names.At(
i - num_positional_fields);
99 MakeNameAssemblerSafe(
buffer);
102void TypeTestingStubNamer::MakeNameAssemblerSafe(BaseTextBuffer*
buffer) {
103 char* cursor =
buffer->buffer();
104 while (*cursor !=
'\0') {
106 if (!((c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') ||
107 (c >=
'0' && c <=
'9') || (c ==
'_'))) {
116 bool lazy_specialize ) {
126 if (
type.IsTopTypeForSubtyping()) {
127 return StubCode::TopTypeTypeTest().ptr();
129 if (
type.IsTypeParameter()) {
132 return StubCode::NullableTypeParameterTypeTest().ptr();
134 return StubCode::TypeParameterTypeTest().ptr();
138 if (
type.IsFunctionType()) {
140 return nullable ? StubCode::DefaultNullableTypeTest().ptr()
141 : StubCode::DefaultTypeTest().ptr();
144 if (
type.IsType() ||
type.IsRecordType()) {
145 const bool should_specialize = !FLAG_precompiled_mode && lazy_specialize;
147 if (should_specialize) {
148 return nullable ? StubCode::LazySpecializeNullableTypeTest().ptr()
149 : StubCode::LazySpecializeTypeTest().ptr();
151 return nullable ? StubCode::DefaultNullableTypeTest().ptr()
152 : StubCode::DefaultTypeTest().ptr();
156 return StubCode::UnreachableTypeTest().ptr();
159#if !defined(DART_PRECOMPILED_RUNTIME)
169 : object_store_(
IsolateGroup::Current()->object_store()) {}
173#if !defined(TARGET_ARCH_IA32)
176 if (
type.IsTypeParameter()) {
181 if (
type.IsTopTypeForSubtyping()) {
182 return StubCode::TopTypeTypeTest().ptr();
185 if (
type.IsCanonical()) {
188 if (
type.IsType() ||
type.IsRecordType()) {
189#if !defined(DART_PRECOMPILED_RUNTIME)
192 if (!
code.IsNull()) {
196 if (!
error.IsNull()) {
197 if (
error.ptr() == Object::out_of_memory_error().ptr()) {
217#if !defined(TARGET_ARCH_IA32)
218#if !defined(DART_PRECOMPILED_RUNTIME)
223 volatile intptr_t far_branch_level = 0;
226 if (setjmp(*jump.
Set()) == 0) {
229 return fun(assembler);
233 if (
error.ptr() == Object::branch_offset_error().ptr()) {
234 ASSERT(far_branch_level < 2);
236 }
else if (
error.ptr() == Object::out_of_memory_error().ptr()) {
246CodePtr TypeTestingStubGenerator::BuildCodeForType(
const AbstractType&
type) {
248 auto zone = thread->
zone();
252 if (!hi->CanUseSubtypeRangeCheckFor(
type) &&
253 !hi->CanUseGenericSubtypeRangeCheckFor(
type) &&
254 !hi->CanUseRecordSubtypeRangeCheckFor(
type)) {
259 if (FLAG_precompiled_mode) {
263 CompilerState compiler_state(thread, FLAG_precompiled_mode,
269 thread, [&](compiler::Assembler& assembler) {
271 BuildOptimizedTypeTestStub(&assembler, &unresolved_calls,
272 slow_tts_stub, hi,
type);
276 zone, &unresolved_calls));
279 const auto pool_attachment =
284 auto install_code_fun = [&]() {
287 if (!static_calls_table.IsNull()) {
288 code.set_static_calls_target_table(static_calls_table);
297 SafepointWriteRwLocker ml(thread,
307 if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
311 DisassembleToStdout formatter;
312 code.Disassemble(&formatter);
314 const ObjectPool& object_pool =
316 if (!object_pool.IsNull()) {
317 object_pool.DebugPrint();
327void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
328 compiler::Assembler* assembler,
330 const Code& slow_type_test_stub,
332 const AbstractType&
type) {
333 BuildOptimizedTypeTestStubFastCases(assembler, hi,
type);
334 __ Jump(compiler::Address(
338void TypeTestingStubGenerator::BuildOptimizedTypeTestStubFastCases(
339 compiler::Assembler* assembler,
341 const AbstractType&
type) {
345 if (
type.IsObjectType()) {
347 compiler::Label is_null;
356 if (
type.IsIntType() ||
type.IsSmiType()) {
357 compiler::Label non_smi_value;
368 if (hi->CanUseSubtypeRangeCheckFor(
type)) {
370 ASSERT(!type_class.IsNull());
376 compiler::Label is_subtype, is_not_subtype;
377 const bool smi_is_ok =
386 BuildOptimizedSubtypeRangeCheck(assembler, ranges,
392 }
else if (hi->CanUseGenericSubtypeRangeCheckFor(
type)) {
394 ASSERT(!type_class.IsNull());
395 BuildOptimizedSubclassRangeCheckWithTypeArguments(
396 assembler, hi, Type::Cast(
type), type_class);
397 }
else if (hi->CanUseRecordSubtypeRangeCheckFor(
type)) {
398 BuildOptimizedRecordSubtypeRangeCheck(assembler, hi,
399 RecordType::Cast(
type));
406 compiler::Label non_null;
421 __ Comment(
"No valid cids to check");
424 if ((ranges.
length() == 1) && ranges[0].IsSingleCid()) {
425 const auto& cls =
Class::Handle(zone, class_table->
At(ranges[0].cid_start));
426 __ Comment(
"Checking for cid %" Pd " (%s)", cls.id(),
427 cls.ScrubbedNameCString());
430 __ Comment(
"Checking for concrete finalized classes:");
432 for (
const auto& range : ranges) {
433 ASSERT(!range.IsIllegalRange());
437 cls = class_table->
At(
cid);
438 if (cls.is_abstract())
continue;
439 __ Comment(
" * %" Pd32 " (%s)",
cid, cls.ScrubbedNameCString());
476 const Class& type_class,
477 const Class& to_check) {
497 auto& calculated_type =
499 if (calculated_type.IsInstantiated()) {
500 if (
type.IsInstantiated()) {
525 const bool type_args_consistent = calculated_type_args.IsSubvectorEquivalent(
537 const Class& type_class,
542 __ Comment(
"Not checking the following concrete implementors of %s:",
549 for (
const auto& range : ranges) {
550 ASSERT(!range.IsIllegalRange());
554 cls = class_table->
At(
cid);
555 if (cls.is_abstract())
continue;
556 ASSERT(cls.is_type_finalized());
558 buffer.Printf(
" * %" Pd32 "(%s): ",
cid, cls.ScrubbedNameCString());
561 calculated_type = cls.GetInstantiationOf(zone, type_class);
562 buffer.AddString(
"cannot check that ");
564 buffer.AddString(
" is a subtype of ");
568 calculated_type = cls.GetInstantiationOf(zone, type_class);
570 buffer.AddString(
" is not a subtype of ");
574 buffer.AddString(
"is not finalized");
577 buffer.AddString(
"was not finalized during class splitting");
596bool TypeTestingStubGenerator::BuildOptimizedSubtypeRangeCheck(
597 compiler::Assembler* assembler,
600 compiler::Label* check_succeeded,
601 compiler::Label* check_failed) {
604 assembler, class_id_reg, ranges, check_succeeded, check_failed,
true);
607void TypeTestingStubGenerator::
608 BuildOptimizedSubclassRangeCheckWithTypeArguments(
609 compiler::Assembler* assembler,
612 const Class& type_class) {
613 ASSERT(hi->CanUseGenericSubtypeRangeCheckFor(
type));
614 compiler::Label check_failed, load_succeeded;
617 if (BuildLoadInstanceTypeArguments(assembler, hi,
type, type_class,
620 &load_succeeded, &check_failed)) {
638 Object::null_object());
639 __ BranchIf(
EQUAL, &check_failed);
650 Object::null_object());
651 compiler::Label check_instance_tav;
655 __ Bind(&check_instance_tav);
660 compiler::Label pop_saved_registers_on_failure;
661 const RegisterSet saved_registers(
663 __ PushRegisters(saved_registers);
667 const intptr_t num_type_parameters = type_class.NumTypeParameters();
668 const intptr_t num_type_arguments = type_class.NumTypeArguments();
669 ASSERT(ta.Length() == num_type_parameters);
670 for (intptr_t
i = 0;
i < num_type_parameters; ++
i) {
671 const intptr_t type_param_value_offset_i =
672 num_type_arguments - num_type_parameters +
i;
674 type_arg = ta.TypeAt(
i);
675 ASSERT(type_arg.IsTypeParameter() ||
676 hi->CanUseSubtypeRangeCheckFor(type_arg));
678 if (type_arg.IsTypeParameter()) {
679 BuildOptimizedTypeParameterArgumentValueCheck(
680 assembler, hi, TypeParameter::Cast(type_arg),
681 type_param_value_offset_i, &pop_saved_registers_on_failure);
683 BuildOptimizedTypeArgumentValueCheck(
684 assembler, hi, Type::Cast(type_arg), type_param_value_offset_i,
685 &pop_saved_registers_on_failure);
688 __ PopRegisters(saved_registers);
690 __ Bind(&pop_saved_registers_on_failure);
691 __ PopRegisters(saved_registers);
698void TypeTestingStubGenerator::BuildOptimizedRecordSubtypeRangeCheck(
699 compiler::Assembler* assembler,
701 const RecordType&
type) {
702 compiler::Label is_subtype, is_not_subtype;
710 __ BranchIf(
EQUAL, &is_subtype);
715 __ LoadCompressedSmi(
726 for (intptr_t
i = 0, n =
type.NumFields();
i < n; ++
i) {
727 compiler::Label
next;
729 field_type =
type.FieldTypeAt(
i);
730 ASSERT(hi->CanUseSubtypeRangeCheckFor(field_type));
736 field_type_class = field_type.type_class();
737 ASSERT(!field_type_class.IsNull());
744 const bool smi_is_ok = smi_type.IsSubtypeOf(field_type,
Heap::kNew);
746 smi_is_ok ? &
next : &is_not_subtype);
749 BuildOptimizedSubtypeRangeCheck(assembler, ranges,
776 const Class& type_class,
782 Zone*
const Z =
T->zone();
783 ClassTable*
const class_table =
T->isolate_group()->class_table();
788 auto add_to_vector = [&](intptr_t tav_offset,
const CidRange& range) {
789 if (range.cid_start == -1)
return;
796 offset_map.
Insert(tav_offset, vector);
800 auto increment_count = [&](intptr_t
cid, intptr_t tav_offset) {
802 predefined_offsets.
Update(
803 {tav_offset, predefined_offsets.
Lookup(tav_offset) + 1});
804 }
else if (
auto*
const kv = predefined_offsets.
LookupPair(tav_offset)) {
805 predefined_offsets.
Update({kv->key, kv->value + 1});
807 user_defined_offsets.
Update(
808 {tav_offset, user_defined_offsets.
Lookup(tav_offset) + 1});
814 for (
const auto& range : ranges) {
816 intptr_t cid_start = -1;
817 intptr_t cid_end = -1;
818 for (intptr_t
cid = range.cid_start;
cid <= range.cid_end;
cid++) {
820 cls = class_table->
At(
cid);
821 if (cls.is_abstract())
continue;
824 ASSERT(cls.is_finalized());
825 const intptr_t tav_offset =
828 if (tav_offset == last_offset && cid_start >= 0) {
830 increment_count(
cid, tav_offset);
833 add_to_vector(last_offset, {cid_start, cid_end});
834 last_offset = tav_offset;
835 cid_start = cid_end =
cid;
836 increment_count(
cid, tav_offset);
838 add_to_vector(last_offset, {cid_start, cid_end});
845 const intptr_t type_class_offset =
848 user_defined_offsets.
LookupPair(type_class_offset) !=
nullptr);
850 ASSERT(vector !=
nullptr);
853 predefined_offsets.
Remove(type_class_offset);
854 user_defined_offsets.
Remove(type_class_offset);
859 auto predefined_it = predefined_offsets.
GetIterator();
860 while (
auto*
const kv = predefined_it.Next()) {
862 ASSERT(vector !=
nullptr);
868 auto user_defined_it = user_defined_offsets.
GetIterator();
869 while (
auto*
const kv = user_defined_it.Next()) {
871 ASSERT(vector !=
nullptr);
904 const Class& type_class,
917 if (range.cid_start == -1)
return;
920 cid_check_only->
Add(range);
923 type_argument_checks->
Add(range);
926 not_checked->
Add(range);
929 for (
const auto& range : ranges) {
935 to_check = class_table->
At(
cid);
936 if (to_check.is_abstract())
continue;
940 to_check.is_finalized());
941 if (last_check == current_check && cid_start >= 0) {
945 add_cid_range(last_check, {cid_start, cid_end});
946 last_check = current_check;
947 cid_start = cid_end =
cid;
949 add_cid_range(last_check, {cid_start, cid_end});
953bool TypeTestingStubGenerator::BuildLoadInstanceTypeArguments(
954 compiler::Assembler* assembler,
957 const Class& type_class,
959 const Register instance_type_args_reg,
960 compiler::Label* load_succeeded,
961 compiler::Label* load_failed) {
963 hi->SubtypeRangesForClass(type_class,
false,
965 if (ranges.is_empty()) {
970 if (!type_class.is_implemented()) {
971 ASSERT(type_class.is_finalized());
972 const intptr_t tav_offset =
974 compiler::Label is_subtype;
976 BuildOptimizedSubtypeRangeCheck(assembler, ranges, class_id_reg,
977 &is_subtype, load_failed);
981 __ LoadCompressedFieldFromOffset(instance_type_args_reg,
990 Thread*
const T = hi->thread();
991 Zone*
const Z =
T->zone();
992 CidRangeVector cid_checks_only, type_argument_checks, not_checked;
994 &type_argument_checks, ¬_checked);
996 const bool smi_valid =
1003 (!cid_checks_only.is_empty() || !type_argument_checks.is_empty())) {
1008 bool cid_needs_reload =
true;
1009 if (!cid_checks_only.is_empty()) {
1010 compiler::Label is_subtype, keep_looking;
1011 compiler::Label* check_failed =
1012 type_argument_checks.is_empty() ? load_failed : &keep_looking;
1018 cid_needs_reload = BuildOptimizedSubtypeRangeCheck(
1019 assembler, cid_checks_only, class_id_reg, &is_subtype, check_failed);
1024 if (!type_argument_checks.is_empty()) {
1025 GrowableArray<CidRangeVector*> vectors;
1028 ASSERT(vectors.length() > 0);
1029 ClassTable*
const class_table =
T->isolate_group()->class_table();
1031 for (intptr_t
i = 0;
i < vectors.length();
i++) {
1033 ASSERT(!vector->is_empty());
1034 const intptr_t first_cid = vector->At(0).cid_start;
1035 ASSERT(class_table->HasValidClassAt(first_cid));
1036 cls = class_table->At(first_cid);
1037 ASSERT(cls.is_finalized());
1038 const intptr_t tav_offset =
1040 compiler::Label load_tav, keep_looking;
1043 compiler::Label* check_failed =
1044 i < vectors.length() - 1 ? &keep_looking : load_failed;
1045 if (cid_needs_reload) {
1048 cid_needs_reload = BuildOptimizedSubtypeRangeCheck(
1049 assembler, *vector, class_id_reg, &load_tav, check_failed);
1051 __ LoadCompressedFieldFromOffset(instance_type_args_reg,
1053 if (
i < vectors.length() - 1) {
1054 __ Jump(load_succeeded);
1061 if (!not_checked.is_empty()) {
1064 return !type_argument_checks.is_empty();
1067void TypeTestingStubGenerator::BuildOptimizedTypeParameterArgumentValueCheck(
1068 compiler::Assembler* assembler,
1070 const TypeParameter& type_param,
1071 intptr_t type_param_value_offset_i,
1072 compiler::Label* check_failed) {
1073 if (assembler->EmittingComments()) {
1075 buffer.Printf(
"Generating check for type argument %" Pd ": ",
1076 type_param_value_offset_i);
1082 type_param.IsClassTypeParameter()
1086 compiler::Label is_subtype;
1089 __ CompareObject(kTypeArgumentsReg, Object::null_object());
1090 __ BranchIf(
EQUAL, &is_subtype);
1092 __ LoadCompressedFieldFromOffset(
1095 __ LoadCompressedFieldFromOffset(
1099 type_param_value_offset_i));
1102 __ BranchIf(
EQUAL, &is_subtype);
1104 __ Comment(
"Checking instantiated type parameter for possible top types");
1105 compiler::Label check_subtype_type_class_ids;
1109 __ BranchIf(
NOT_EQUAL, &check_subtype_type_class_ids);
1113 __ BranchIf(
EQUAL, &is_subtype);
1115 __ BranchIf(
EQUAL, &is_subtype);
1117 __ BranchIf(
NOT_EQUAL, &check_subtype_type_class_ids);
1119 __ CompareAbstractTypeNullabilityWith(
1124 __ Comment(
"Checking for legacy or non-nullable instance type argument");
1125 __ CompareAbstractTypeNullabilityWith(
1129 __ BranchIf(
EQUAL, check_failed);
1130 __ Jump(&is_subtype);
1132 __ Bind(&check_subtype_type_class_ids);
1133 __ Comment(
"Checking instance type argument for possible bottom types");
1142 __ BranchIf(
EQUAL, &is_subtype);
1147 __ Comment(
"Checking for legacy or nullable instantiated type parameter");
1148 __ CompareAbstractTypeNullabilityWith(
1152 __ BranchIf(
EQUAL, check_failed);
1159void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
1160 compiler::Assembler* assembler,
1163 intptr_t type_param_value_offset_i,
1164 compiler::Label* check_failed) {
1166 if (
type.IsTopTypeForSubtyping()) {
1172 if (assembler->EmittingComments()) {
1174 buffer.Printf(
"Generating check for type argument %" Pd ": ",
1175 type_param_value_offset_i);
1180 compiler::Label is_subtype, sub_is_type;
1181 __ LoadCompressedFieldFromOffset(
1185 type_param_value_offset_i));
1188 if (
type.IsObjectType() ||
type.IsDartFunctionType() ||
1189 type.IsDartRecordType()) {
1191 __ BranchIf(
EQUAL, &sub_is_type);
1192 if (
type.IsDartFunctionType()) {
1193 __ Comment(
"Checks for Function type");
1196 }
else if (
type.IsDartRecordType()) {
1197 __ Comment(
"Checks for Record type");
1201 __ Comment(
"Checks for Object type");
1203 if (
type.IsNonNullable()) {
1205 __ CompareAbstractTypeNullabilityWith(
1209 __ BranchIf(
EQUAL, check_failed);
1220 __ Comment(
"Checks for Type");
1222 if (
type.IsNonNullable()) {
1224 __ CompareAbstractTypeNullabilityWith(
1228 __ BranchIf(
EQUAL, check_failed);
1233 if (!
type.IsObjectType()) {
1240 __ BranchIf(
EQUAL, &is_subtype);
1241 if (null_is_assignable) {
1243 __ BranchIf(
EQUAL, &is_subtype);
1249 hi->SubtypeRangesForClass(type_class,
1251 !null_is_assignable);
1252 BuildOptimizedSubtypeRangeCheck(assembler, ranges,
1284 if (
ConstantInstr* constant = type_arguments->AsConstant()) {
1285 const Object&
object = constant->value();
1291 type_arguments->AsInstantiateTypeArguments()) {
1292 if (instantiate->type_arguments()->BindsToConstant() &&
1293 !instantiate->type_arguments()->BoundConstant().IsNull()) {
1295 TypeArguments::Cast(instantiate->type_arguments()->BoundConstant());
1298 }
else if (
LoadFieldInstr* load_field = type_arguments->AsLoadField()) {
1309 if (
type.IsType()) {
1312 cid = type_class.
id();
1317 const Class& instance_klass =
1319 if (load_field->slot().IsTypeArguments() && instance_klass.
IsGeneric() &&
1321 load_field->slot().offset_in_bytes()) {
1330 klass, declaration_type_args);
1333 }
else if (type_arguments->IsParameter() ||
1334 type_arguments->IsLoadIndexedUnsafe()) {
1346 klass, declaration_type_args);
1351 ASSERT(type_arguments->IsPhi() || type_arguments->IsStaticCall());
1359#if !defined(DART_PRECOMPILED_RUNTIME)
1361 TypeUsageInfo* type_usage_info,
1363 Definition* type_arguments) {
1375 zone_(thread->zone()),
1376 assert_assignable_types_(),
1377 instance_creation_arguments_(
1379 [thread->isolate_group()->class_table()->NumCids()]),
1380 klass_(
Class::Handle(zone_)) {
1386 delete[] instance_creation_arguments_;
1390 if (!assert_assignable_types_.
HasKey(&
type)) {
1391 AddTypeToSet(&assert_assignable_types_, &
type);
1420 klass_ = klass.
ptr();
1422 const intptr_t
cid = klass_.
id();
1424 if (!
set.HasKey(&ta)) {
1434 const intptr_t cid_count = class_table->
NumCids();
1438 CollectTypeParametersUsedInAssertAssignable(¶meters_tested_against);
1442 UpdateAssertAssignableTypes(class_table, cid_count,
1443 ¶meters_tested_against);
1446void TypeUsageInfo::CollectTypeParametersUsedInAssertAssignable(
1452 AddToSetIfParameter(
set, *
type, ¶m);
1456void TypeUsageInfo::UpdateAssertAssignableTypes(
1457 ClassTable* class_table,
1471 for (intptr_t
cid = 0;
cid < cid_count; ++
cid) {
1472 if (!class_table->IsValidIndex(
cid) || !class_table->HasValidClassAt(
cid)) {
1475 klass = class_table->At(
cid);
1476 if (klass.NumTypeArguments() <= 0) {
1480 const intptr_t num_parameters = klass.NumTypeParameters();
1481 for (intptr_t
i = 0;
i < num_parameters; ++
i) {
1482 param = klass.TypeParameterAt(
i);
1483 if (parameters_tested_against->HasKey(¶m)) {
1484 TypeArgumentsSet& ta_set = instance_creation_arguments_[
cid];
1486 for (
const TypeArguments** ta = it.Next(); ta !=
nullptr;
1490 if (!(*ta)->IsNull()) {
1491 type = (*ta)->TypeAt(
i);
1492 if (
type.IsInstantiated()) {
1503 const AbstractType*
type,
1504 TypeParameter* param) {
1505 if (
type->IsTypeParameter()) {
1506 *param ^=
type->ptr();
1507 if (!param->IsNull() && !
set->HasKey(param)) {
1513void TypeUsageInfo::AddTypeToSet(TypeSet*
set,
const AbstractType*
type) {
1520 if (
type.IsFinalized()) {
1521 return assert_assignable_types_.
HasKey(&
type);
1526#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
1537 if (object->IsType() || object->IsRecordType()) {
1538 types_->Add(&AbstractType::CheckedHandle(zone_,
object));
1539 }
else if (object->IsSubtypeTestCache()) {
1559 CollectTypes visitor(zone, &types);
1563 for (
auto*
const type : types) {
1565 type->SetTypeTestingStub(stub);
static float next(float f)
#define check(reporter, ref, unref, make, kill)
#define ASSERT_EQUAL(expected, actual)
bool Remove(typename KeyValueTrait::Key key)
void Update(typename KeyValueTrait::Pair kv)
bool HasKey(typename KeyValueTrait::Key key) const
Iterator GetIterator() const
static bool ContainsCid(const CidRangeVector &ranges, intptr_t cid)
ClassPtr At(intptr_t cid) const
bool HasValidClassAt(intptr_t cid) const
const char * ScrubbedNameCString() const
LibraryPtr library() const
TypePtr GetInstantiationOf(Zone *zone, const Class &cls) const
TypeArgumentsPtr GetDeclarationInstanceTypeArguments() const
intptr_t NumTypeArguments() const
bool is_type_finalized() const
bool FindInstantiationOf(Zone *zone, const Class &cls, GrowableArray< const Type * > *path, bool consider_only_super_classes=false) const
ClassPtr SuperClass(ClassTable *class_table=nullptr) const
bool is_implemented() const
bool is_finalized() const
static void NotifyCodeObservers(const Code &code, bool optimized)
static CodePtr FinalizeCode(FlowGraphCompiler *compiler, compiler::Assembler *assembler, PoolAttachment pool_attachment, bool optimized, CodeStatistics *stats)
static DART_NORETURN void ThrowOOM()
static bool GenerateCidRangesCheck(compiler::Assembler *assembler, Register class_id_reg, const CidRangeVector &cid_ranges, compiler::Label *inside_range_lbl, compiler::Label *outside_range_lbl=nullptr, bool fall_through_if_inside=false)
void IterateObjects(ObjectVisitor *visitor) const
static bool NullIsAssignableTo(const AbstractType &other)
V Lookup(const Key &key) const
Pair * LookupPair(const Key &key) const
void Insert(const Key &key, const Value &value)
ObjectStore * object_store() const
SafepointRwLock * program_lock()
static IsolateGroup * Current()
ClassTable * class_table() const
void RunWithStoppedMutators(T single_current_mutator, S otherwise, bool use_force_growth_in_otherwise=false)
static ObjectPtr RawCast(ObjectPtr obj)
static Object & ZoneHandle()
static intptr_t RawValue(intptr_t value)
static const char * ToCString(Thread *thread, StringPtr ptr)
static bool HasBeenInitialized()
HierarchyInfo * hierarchy_info() const
void set_type_usage_info(TypeUsageInfo *value)
static Thread * Current()
DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError()
void set_sticky_error(const Error &value)
IsolateGroup * isolate_group() const
bool IsInstantiated(Genericity genericity=kAny, intptr_t num_free_fun_type_params=kAllFree) const
static CodePtr DefaultCodeForType(const AbstractType &type, bool lazy_specialize=true)
CodePtr OptimizedCodeForType(const AbstractType &type)
static CodePtr SpecializeStubFor(Thread *thread, const AbstractType &type)
TypeTestingStubGenerator()
void WriteStubNameForTypeTo(BaseTextBuffer *buffer, const AbstractType &type) const
const char * StubNameForType(const AbstractType &type) const
bool IsUsedInTypeTest(const AbstractType &type)
void BuildTypeUsageInformation()
TypeUsageInfo(Thread *thread)
void UseTypeArgumentsInInstanceCreation(const Class &klass, const TypeArguments &ta)
void UseTypeInAssertAssignable(const AbstractType &type)
static TypePtr ObjectType()
static TypePtr DynamicType()
void static bool EmittingComments()
static ArrayPtr BuildStaticCallsTable(Zone *zone, compiler::UnresolvedPcRelativeCalls *unresolved_calls)
static const word kNoTypeArguments
static intptr_t TypeArgumentsFieldOffset(const dart::Class &klass)
static word field_offset(intptr_t index)
static word shape_offset()
static word slow_type_test_entry_point_offset()
static word type_at_offset(intptr_t i)
#define THR_Print(format,...)
const uint8_t uint32_t uint32_t GError ** error
Dart_NativeFunction function
#define HANDLESCOPE(thread)
GrowableArray< UnresolvedPcRelativeCall * > UnresolvedPcRelativeCalls
static void CommentSkippedClasses(compiler::Assembler *assembler, const Type &type, const Class &type_class, const CidRangeVector &ranges)
static CodePtr RetryCompilationWithFarBranches(Thread *thread, std::function< CodePtr(compiler::Assembler &)> fun)
@ kInstanceTypeArgumentsAreSubtypes
DART_EXPORT bool IsNull(Dart_Handle object)
static CheckType SubtypeChecksForClass(Zone *zone, const Type &type, const Class &type_class, const Class &to_check)
void DeoptimizeTypeTestingStubs()
MallocGrowableArray< CidRangeValue > CidRangeVector
void RegisterTypeArgumentsUse(const Function &function, TypeUsageInfo *type_usage_info, const Class &klass, Definition *type_arguments)
static void SplitOnTypeArgumentTests(HierarchyInfo *hi, const Type &type, const Class &type_class, const CidRangeVector &ranges, CidRangeVector *cid_check_only, CidRangeVector *type_argument_checks, CidRangeVector *not_checked)
DirectChainedHashMap< TypeParameterKeyValueTrait > TypeParameterSet
static void CommentCheckedClasses(compiler::Assembler *assembler, const CidRangeVector &ranges)
static void SplitByTypeArgumentsFieldOffset(Thread *T, const Class &type_class, const CidRangeVector &ranges, GrowableArray< CidRangeVector * > *output)
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
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 set
static bool Bind(PassBindingsCacheMTL &pass, ShaderStage stage, size_t bind_index, const BufferView &view)
static constexpr intptr_t kSavedTypeArgumentRegisters
static constexpr Register kSuperTypeArgumentReg
static constexpr Register kSubTypeArgumentReg
static constexpr Register kInstanceTypeArgumentsReg
static constexpr Register kScratchReg
static constexpr Register kInstanceReg
static constexpr Register kFunctionTypeArgumentsReg
static constexpr Register kInstantiatorTypeArgumentsReg
#define TIMELINE_DURATION(thread, stream, name)