21#if !defined(TARGET_ARCH_IA32)
29 trace_type_testing_stub_tests,
31 "Trace type testing stub tests");
33 print_type_testing_stub_test_headers,
35 "Print headers for executed type testing stub tests");
40 : old_trace_type_checks_(FLAG_trace_type_checks),
41 old_disassemble_stubs_(FLAG_disassemble_stubs) {
42 if (FLAG_trace_type_testing_stub_tests) {
44 FLAG_trace_type_checks =
true;
46#if defined(FORCE_INCLUDE_DISASSEMBLER) || !defined(PRODUCT)
47 FLAG_disassemble_stubs =
true;
52 if (FLAG_trace_type_testing_stub_tests) {
54 FLAG_trace_type_checks = old_trace_type_checks_;
56#if defined(FORCE_INCLUDE_DISASSEMBLER) || !defined(PRODUCT)
57 FLAG_disassemble_stubs = old_disassemble_stubs_;
63 const bool old_trace_type_checks_;
64 const bool old_disassemble_stubs_;
70 auto calculate_breadcrumb = [](
const Register& reg) {
71 return 0x10 + 2 * (
static_cast<intptr_t
>(reg));
81 __ LoadImmediate(reg, calculate_breadcrumb(reg));
85 const intptr_t instance_offset =
87 const intptr_t inst_type_args_offset =
89 const intptr_t fun_type_args_offset =
91 const intptr_t dst_type_offset =
96 inst_type_args_offset);
98 fun_type_args_offset);
101 const intptr_t subtype_test_cache_index =
__ object_pool_builder().AddObject(
103 const intptr_t dst_name_index =
__ object_pool_builder().AddObject(
105 ASSERT_EQUAL(subtype_test_cache_index + 1, dst_name_index);
127 __ Bind(&instance_matches);
129 __ Bind(&done_with_instance);
143 fun_type_args_offset);
147 inst_type_args_offset);
171 __ CompareImmediate(reg, calculate_breadcrumb(reg));
201extern bool TESTING_runtime_entered_on_TTS_invocation;
202extern bool TESTING_found_hash_STC_entry;
245 "passes in STC stub",
246 "passes in runtime, adding new STC entry",
247 "passes in runtime, no changes to max size STC",
248 "passes in runtime, initial TTS stub specialization",
249 "passes in runtime, TTS stub respecialized",
255 "kTestResultStrings has too few entries");
258 "kTestResultStrings has extra entries");
300 const auto& other_closure = Closure::Cast(other.
instance);
305 return sig.ptr() == other_sig.ptr() &&
306 closure.instantiator_type_arguments() ==
307 other_closure.instantiator_type_arguments() &&
308 closure.function_type_arguments() ==
309 other_closure.function_type_arguments() &&
310 closure.delayed_type_arguments() ==
311 other_closure.delayed_type_arguments();
315 if (
cid != other_cid) {
319 if (cls.NumTypeArguments() == 0) {
322 return Instance::Cast(
instance).GetTypeArguments() ==
323 Instance::Cast(other.
instance).GetTypeArguments();
328 Bool* out_result =
nullptr,
329 intptr_t* out_index =
nullptr)
const {
330 if (
cache.IsNull())
return false;
335 const auto& closure_instantiator_type_arguments =
337 const auto& closure_function_type_arguments =
339 const auto& closure_delayed_type_arguments =
341 return cache.HasCheck(
344 closure_delayed_type_arguments, out_index, out_result);
349 if (cls.NumTypeArguments() > 0) {
350 instance_type_arguments = Instance::Cast(
instance).GetTypeArguments();
352 return cache.HasCheck(id_smi, dst_type, instance_type_arguments,
354 Object::null_type_arguments(),
355 Object::null_type_arguments(), out_index, out_result);
359 DISALLOW_ALLOCATION();
404 Code::Handle(
zone(), CreateInvocationStub(thread_,
zone()))),
406 arguments_descriptor_(
408 previous_tts_stub_(
Code::Handle(
zone())),
412 new_tts_stub_(
Code::Handle(
zone())),
415 if (FLAG_print_type_testing_stub_test_headers) {
416 THR_Print(
"Creating test state for type %s\n",
type.ToCString());
428 if (type_.IsTypeParameter()) {
429 return TypeParameter::Cast(type_).GetFromTypeArguments(
436 pool_.
SetObjectAt(kSubtypeTestCacheIndex, Object::null_object());
449 thread_, last_tested_type_);
452 PrintInvocationHeader(
"eagerly specialized", test_case);
453 InvokeStubHelper(test_case);
456 EXPECT(previous_tts_stub_.
ptr() == new_tts_stub_.
ptr());
460 bool should_specialize =
true) {
466 const auto& specializing_stub =
468 last_tested_type_,
true));
475 PrintInvocationHeader(
"lazy specialized", initial_case);
476 InvokeStubHelper(initial_case);
478 EXPECT(previous_tts_stub_.
ptr() != new_tts_stub_.
ptr());
480 EXPECT(previous_tts_stub_.
ptr() == new_tts_stub_.
ptr());
488 PrintInvocationHeader(
"existing", test_case);
489 InvokeStubHelper(test_case);
492 previous_tts_stub_.
ptr() != new_tts_stub_.
ptr());
496 static constexpr intptr_t kSubtypeTestCacheIndex = 0;
498 SmiPtr modified_abi_regs()
const {
499 if (modified_abi_regs_box_.
At(0)->IsHeapObject())
return Smi::null();
502 SmiPtr modified_rest_regs()
const {
503 if (modified_rest_regs_box_.
At(0)->IsHeapObject())
return Smi::null();
507 void PrintInvocationHeader(
const char* stub_type,
508 const TTSTestCase& test_case) {
509 if (!FLAG_print_type_testing_stub_test_headers)
return;
513 THR_Print(
"Testing %s %s stub for type %s\n",
514 stub_name ==
nullptr ?
"optimized" : stub_name, stub_type,
516 if (last_tested_type_.
ptr() != type_.
ptr()) {
519 THR_Print(
" Instance: %s\n", test_case.instance.ToCString());
521 test_case.instantiator_tav.ToCString());
522 THR_Print(
" Function TAV: %s\n", test_case.function_tav.ToCString());
527 static CodePtr CreateInvocationStub(Thread* thread, Zone*
zone) {
529 zone, thread->isolate_group()->class_table()->At(kInstanceCid));
535 signature, symbol, UntaggedFunction::kRegularFunction,
false,
536 false,
false,
false,
false, klass, TokenPosition::kNoSource));
538 TraceStubInvocationScope scope;
539 compiler::ObjectPoolBuilder pool_builder;
540 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
541 compiler::Assembler assembler(&pool_builder);
549 invoke_tts.set_object_pool(
pool.ptr());
551 invoke_tts.set_exception_handlers(
553 EXPECT_EQ(2,
pool.Length());
555 if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
559 return invoke_tts.ptr();
562 void InvokeStubHelper(
const TTSTestCase& test_case) {
563 ASSERT(test_case.instantiator_tav.IsNull() ||
564 test_case.instantiator_tav.IsCanonical());
565 ASSERT(test_case.function_tav.IsNull() ||
566 test_case.function_tav.IsCanonical());
568 modified_abi_regs_box_.
SetAt(0, Object::null_object());
569 modified_rest_regs_box_.
SetAt(0, Object::null_object());
572 last_arguments_.
SetAt(0, modified_abi_regs_box_);
573 last_arguments_.
SetAt(1, modified_rest_regs_box_);
574 last_arguments_.
SetAt(2, test_case.instance);
575 last_arguments_.
SetAt(3, test_case.instantiator_tav);
576 last_arguments_.
SetAt(4, test_case.function_tav);
577 last_arguments_.
SetAt(5, type_);
582 SafepointMutexLocker ml(
584 previous_stc_ = previous_stc_.
Copy(thread_);
588 TESTING_runtime_entered_on_TTS_invocation =
false;
591 TraceStubInvocationScope scope;
592 last_result_ = DartEntry::InvokeCode(tts_invoker_, arguments_descriptor_,
593 last_arguments_, thread_);
596 EXPECT_EQ(test_case.ShouldEnterRuntime(),
597 TESTING_runtime_entered_on_TTS_invocation);
601 if (test_case.expected_result ==
kFail) {
603 EXPECT(last_result_.IsError());
604 EXPECT(last_result_.IsUnhandledException());
605 if (last_result_.IsUnhandledException()) {
607 UnhandledException::Cast(last_result_).exception());
612 if (!last_result_.
IsNull()) {
613 EXPECT(last_result_.IsError());
614 EXPECT(last_result_.IsUnhandledException());
615 if (last_result_.IsUnhandledException()) {
616 const auto& exception = UnhandledException::Cast(last_result_);
617 FAIL(
"%s", exception.ToErrorCString());
620 EXPECT(new_tts_stub_.
ptr() != StubCode::LazySpecializeTypeTest().ptr());
621 ReportModifiedRegisters(modified_abi_regs());
624 if (!test_case.ShouldEnterRuntime()) {
625 ReportModifiedRegisters(modified_rest_regs());
629 ReportUnexpectedSTCChanges(test_case);
632 static void ReportModifiedRegisters(SmiPtr encoded_reg_mask) {
634 FAIL(
"No modified register information");
637 const intptr_t reg_mask =
Smi::Value(encoded_reg_mask);
639 if (((1 <<
i) & reg_mask) != 0) {
646 void ReportMissingOrChangedEntries(
const SubtypeTestCache& old_cache,
647 const SubtypeTestCache& new_cache) {
657 SafepointMutexLocker ml(
660 while (old_cache.GetNextCheck(&
i, &cid_or_sig, &
type, &instance_type_args,
661 &instantiator_type_args, &function_type_args,
662 &instance_parent_type_args,
663 &instance_delayed_type_args, &old_result)) {
664 if (!new_cache.HasCheck(
665 cid_or_sig,
type, instance_type_args, instantiator_type_args,
666 function_type_args, instance_parent_type_args,
667 instance_delayed_type_args,
nullptr, &new_result)) {
668 FAIL(
"New STC is missing check in old STC");
670 if (old_result.value() != new_result.value()) {
671 FAIL(
"New STC has different result from old STC");
678 bool ShouldUpdateCache(
const TTSTestCase& test_case)
const {
682 const bool would_update_cache_if_not_lazy =
683 !test_case.instance.IsNull() &&
685 StubCode::DefaultNullableTypeTest().ptr() ||
687 StubCode::DefaultTypeTest().ptr());
688 return would_update_cache_if_not_lazy && previous_stc_.
IsNull();
694 void ReportUnexpectedSTCChanges(
const TTSTestCase& test_case) {
695 const bool hit_check_cap =
696 !previous_stc_.
IsNull() &&
699 const bool should_update_cache = ShouldUpdateCache(test_case);
700 if (should_update_cache) {
702 EXPECT(!test_case.HasSTCEntry(previous_stc_, type_));
705 if (!last_stc_.
IsNull()) {
712 if (!previous_stc_.
IsNull()) {
714 ReportMissingOrChangedEntries(previous_stc_, last_stc_);
719 if (previous_stc_.
IsNull()) {
723 const auto& previous_array =
726 EXPECT(last_array.Equals(previous_array));
730 const bool has_stc_entry = test_case.HasSTCEntry(last_stc_, type_);
733 const bool expects_stc_entry =
735 if ((!expects_stc_entry && has_stc_entry) ||
736 (expects_stc_entry && !has_stc_entry)) {
738 buffer.Printf(
"%s STC entry for:\n instance:%s\n destination type: %s",
739 expects_stc_entry ?
"Expected" :
"Did not expect",
740 test_case.instance.ToCString(), type_.
ToCString());
741 if (last_tested_type_.
ptr() != type_.
ptr()) {
744 buffer.AddString(
"\ngot:");
746 buffer.AddString(
" null");
749 SafepointMutexLocker ml(
754 FAIL(
"unexpected STC modification");
758 Thread*
const thread_;
759 const AbstractType& type_;
760 const Array& modified_abi_regs_box_;
761 const Array& modified_rest_regs_box_;
762 const Code& tts_invoker_;
763 const ObjectPool& pool_;
764 const Array& arguments_descriptor_;
765 Code& previous_tts_stub_;
766 SubtypeTestCache& previous_stc_;
767 Array& last_arguments_;
768 AbstractType& last_tested_type_;
770 SubtypeTestCache& last_stc_;
771 Object& last_result_;
782 bool should_specialize =
true) {
803 const auto& type_to_test =
805 const bool null_should_specialize =
807 (type_to_test.IsType() || type_to_test.IsRecordType());
810 state.InvokeLazilySpecializedStub(null_test, null_should_specialize);
811 state.InvokeExistingStub(null_test);
815 state.InvokeLazilySpecializedStub(test_case, should_specialize);
817 if (
state.last_stc().IsNull()) {
820 state.InvokeExistingStub(test_case);
827 state.InvokeExistingStub(test_case);
836 state.InvokeEagerlySpecializedStub(null_test);
837 state.InvokeExistingStub(null_test);
840 state.InvokeEagerlySpecializedStub(test_case);
846 state.InvokeExistingStub(test_case);
858 class A extends Base<int> {}
859 class A1 extends A implements I2 {}
860 class A2<T> extends A implements I<int, T> {}
862 class B extends Base<String> {}
863 class B1 extends B implements I2 {}
864 class B2<T> extends B implements I<T, String> {}
866 genericFun<A, B>() {}
868 createI() => I<int, String>();
870 createBaseInt() => Base<int>();
871 createBaseNull() => Base<Null>();
872 createBaseNever() => Base<Never>();
875 createA2() => A2<int>();
878 createB2() => B2<int>();
879 createBaseIStringDouble() => Base<I<String, double>>();
880 createBaseA2Int() => Base<A2<int>>();
881 createBaseA2A1() => Base<A2<A1>>();
882 createBaseB2Int() => Base<B2<int>>();
886 const auto& root_library =
895 const auto& obj_base_int =
897 const auto& obj_base_null =
899 const auto& obj_base_never =
915 tav_object.SetTypeAt(0, type_object);
919 tav_object_dynamic.SetTypeAt(0, type_object);
920 tav_object_dynamic.SetTypeAt(1, type_dynamic);
924 tav_dynamic_t.SetTypeAt(0, type_dynamic);
925 tav_dynamic_t.SetTypeAt(
944 RunTTSTest(type_a, {obj_a, tav_null, tav_null});
945 RunTTSTest(type_a, {obj_a1, tav_null, tav_null});
946 RunTTSTest(type_a, {obj_a2, tav_null, tav_null});
956 RunTTSTest(type_base, {obj_base_int, tav_null, tav_null});
957 RunTTSTest(type_base, {obj_base_null, tav_null, tav_null});
958 RunTTSTest(type_base, {obj_a, tav_null, tav_null});
959 RunTTSTest(type_base, {obj_a1, tav_null, tav_null});
960 RunTTSTest(type_base, {obj_a2, tav_null, tav_null});
961 RunTTSTest(type_base, {obj_b, tav_null, tav_null});
962 RunTTSTest(type_base, {obj_b1, tav_null, tav_null});
963 RunTTSTest(type_base, {obj_b2, tav_null, tav_null});
972 tav_nullable_int.SetTypeAt(0, type_nullable_int);
974 auto& type_base_nullable_int =
977 RunTTSTest(type_base_nullable_int, {obj_base_null, tav_null, tav_null});
978 RunTTSTest(type_base_nullable_int, {obj_base_never, tav_null, tav_null});
984 tav_int.SetTypeAt(0, type_int);
991 RunTTSTest(type_base_int, {obj_base_never, tav_null, tav_null});
996 RunTTSTest(type_i2, {obj_i2, tav_null, tav_null});
999 RunTTSTest(type_i2, {obj_a1, tav_null, tav_null});
1002 RunTTSTest(type_i2, {obj_b1, tav_null, tav_null});
1006 auto& type_i_object_dynamic =
1009 RunTTSTest(type_i_object_dynamic, {obj_i, tav_null, tav_null});
1012 Failure({obj_base_int, tav_null, tav_null}));
1015 RunTTSTest(type_i_object_dynamic, {obj_a2, tav_null, tav_null});
1018 RunTTSTest(type_i_object_dynamic, {obj_b2, tav_null, tav_null});
1027 auto& type_dynamic_t =
1030 RunTTSTest(type_dynamic_t, {obj_i, tav_object, tav_null});
1035 RunTTSTest(type_dynamic_t, {obj_a2, tav_object, tav_null});
1042 auto& type_non_nullable_object =
1043 Type::Handle(isolate_group->object_store()->non_nullable_object_type());
1044 RunTTSTest(type_non_nullable_object, {obj_a, tav_null, tav_null});
1048 const auto& root_library =
1054 const auto& fun_generic =
1059 const auto& obj_base_int =
1067 const auto& obj_basea2int =
1069 const auto& obj_basea2a1 =
1071 const auto& obj_baseb2int =
1073 const auto& obj_baseistringdouble =
1081 auto& type_a1 =
Type::Handle(class_a1.DeclarationType());
1087 tav_object_dynamic.SetTypeAt(0, type_object);
1088 tav_object_dynamic.SetTypeAt(1, type_dynamic);
1092 tav_dynamic_int.SetTypeAt(0, type_dynamic);
1093 tav_dynamic_int.SetTypeAt(1, type_int);
1097 tav_dynamic_string.SetTypeAt(0, type_dynamic);
1098 tav_dynamic_string.SetTypeAt(1, type_string);
1102 tav_int.SetTypeAt(0, type_int);
1105 auto& type_i_object_dynamic =
1109 tav_iod.SetTypeAt(0, type_i_object_dynamic);
1124 auto& type_base_i_object_dynamic =
1127 RunTTSTest(type_base_i_object_dynamic, {obj_baseb2int, tav_null, tav_null});
1129 {obj_baseistringdouble, tav_null, tav_null});
1139 tav_baset.SetTypeAt(
1143 RunTTSTest(type_base_t, {obj_base_int, tav_int, tav_null});
1148 tav_baseb.SetTypeAt(
1153 RunTTSTest(type_base_b, {obj_base_int, tav_null, tav_dynamic_int});
1155 Failure({obj_baseistringdouble, tav_null, tav_dynamic_int}));
1157 RunTTSTest(type_base_b, {obj_base_int, tav_null, tav_null});
1172 auto& type_i_dynamic_string =
1174 type_i_dynamic_string = type_i_dynamic_string.ToNullability(
1177 RunTTSTest(type_i_dynamic_string, {obj_i, tav_null, tav_null});
1179 Failure({obj_base_int, tav_null, tav_null}));
1188 tav_a2_t.SetTypeAt(0, type_a2_t);
1199 tav_a1.SetTypeAt(0, type_a1);
1203 tav_a2_a1.SetTypeAt(0, type_a2_a1);
1216 class B extends A {}
1217 class C implements A {}
1221 getRecordType1() => getType<(int, A)>();
1222 getRecordType2() => getType<(A, int, String)>();
1223 getRecordType3() => getType<(int, D)>();
1225 createObj1() => (1, B());
1226 createObj2() => (1, 'bye');
1227 createObj3() => (1, foo: B());
1228 createObj4() => (1, B(), 2);
1229 createObj5() => (C(), 2, 'hi');
1230 createObj6() => (D(), 2, 'hi');
1231 createObj7() => (3, D<int>());
1232 createObj8() => (D<int>(), 3);
1236 const auto& root_library =
1239 const auto& type1 = AbstractType::Cast(
1241 const auto& type2 = AbstractType::Cast(
1243 const auto& type3 = AbstractType::Cast(
1261 RunTTSTest(type1, {obj1, tav_null, tav_null});
1268 RunTTSTest(type2, {obj5, tav_null, tav_null});
1273 RunTTSTest(type3, {obj7, tav_null, tav_null});
1278 const char* kScript =
1280 abstract class I<T> {}
1281 class B<R> implements I<String> {}
1283 createBInt() => B<int>();
1290 const auto& tav_null = Object::null_type_arguments();
1297 const auto& type_i_t =
Type::Handle(class_i.DeclarationType());
1299 RunTTSTest(type_i_string, {obj_b_int, tav_null, tav_null});
1307 const char* kScript =
1309 import "dart:async";
1311 Future<int> createFutureInt() async => 3;
1312 Future<int Function()> createFutureFunction() async => () => 3;
1313 Future<int Function()?> createFutureNullableFunction() async =>
1314 (() => 3) as int Function()?;
1319 const auto& class_future =
1323 const auto& class_closure =
1325 const auto& obj_futureint =
1327 const auto& obj_futurefunction =
1329 const auto& obj_futurenullablefunction =
1332 const auto& tav_null = Object::null_type_arguments();
1349 tav_dynamic.SetTypeAt(0, Object::dynamic_type());
1352 tav_object.SetTypeAt(0, type_object);
1355 tav_nullable_object.SetTypeAt(0, type_nullable_object);
1358 tav_int.SetTypeAt(0, type_int);
1361 tav_num.SetTypeAt(0, type_num);
1364 tav_string.SetTypeAt(0, type_string);
1379 auto& type_future_int =
1385 auto& type_future_num =
1388 const auto& type_future_t =
Type::Handle(class_future.DeclarationType());
1390 THR_Print(
"********************************************************\n");
1392 THR_Print(
"********************************************************\n\n");
1409 RunTTSTest(type_future, {obj_futureint, tav_null, tav_null});
1410 RunTTSTest(type_future_dynamic, {obj_futureint, tav_null, tav_null});
1411 RunTTSTest(type_future_object, {obj_futureint, tav_null, tav_null});
1412 RunTTSTest(type_future_nullable_object, {obj_futureint, tav_null, tav_null});
1413 RunTTSTest(type_future_int, {obj_futureint, tav_null, tav_null});
1414 RunTTSTest(type_future_num, {obj_futureint, tav_null, tav_null});
1415 RunTTSTest(type_future_t, {obj_futureint, tav_int, tav_null});
1443 auto& type_function_int_nullary =
1447 type_function_int_nullary.set_num_implicit_parameters(1);
1448 type_function_int_nullary.set_num_fixed_parameters(1);
1450 type_function_int_nullary.SetParameterTypeAt(0, Type::dynamic_type());
1451 type_function_int_nullary.set_result_type(type_int);
1453 auto& type_nullable_function_int_nullary =
1459 tav_function.SetTypeAt(0, type_function);
1462 tav_nullable_function.SetTypeAt(0, type_nullable_function);
1465 tav_closure.SetTypeAt(0, type_closure);
1468 tav_nullable_closure.SetTypeAt(0, type_nullable_closure);
1471 tav_function_int_nullary.SetTypeAt(0, type_function_int_nullary);
1473 auto& tav_nullable_function_int_nullary =
1475 tav_nullable_function_int_nullary.SetTypeAt(
1476 0, type_nullable_function_int_nullary);
1491 auto& type_future_function_int_nullary =
1494 auto& type_future_nullable_function_int_nullary =
1498 THR_Print(
"\n********************************************************\n");
1499 THR_Print(
" Testing Future<int Function()>\n");
1500 THR_Print(
"********************************************************\n\n");
1522 RunTTSTest(type_future, {obj_futurefunction, tav_null, tav_null});
1523 RunTTSTest(type_future_dynamic, {obj_futurefunction, tav_null, tav_null});
1525 {obj_futurefunction, tav_null, tav_null});
1526 RunTTSTest(type_future_object, {obj_futurefunction, tav_null, tav_null});
1528 {obj_futurefunction, tav_null, tav_null});
1529 RunTTSTest(type_future_object, {obj_futurefunction, tav_null, tav_null});
1531 {obj_futurefunction, tav_null, tav_null});
1532 RunTTSTest(type_future_function, {obj_futurefunction, tav_null, tav_null});
1533 RunTTSTest(type_future_t, {obj_futurefunction, tav_null, tav_null});
1535 {obj_futurefunction, tav_nullable_object, tav_null});
1536 RunTTSTest(type_future_t, {obj_futurefunction, tav_object, tav_null});
1538 {obj_futurefunction, tav_function_int_nullary, tav_null});
1551 RunTTSTest(type_future_nullable_function_int_nullary,
1556 tav_nullable_function, tav_null}));
1558 FalseNegative({obj_futurefunction, tav_function, tav_null}));
1561 tav_nullable_function_int_nullary, tav_null}));
1573 Failure({obj_futurefunction, tav_null, tav_null}));
1575 Failure({obj_futurefunction, tav_null, tav_null}));
1577 Failure({obj_futurefunction, tav_nullable_closure, tav_null}));
1579 Failure({obj_futurefunction, tav_closure, tav_null}));
1581 THR_Print(
"\n********************************************************\n");
1582 THR_Print(
" Testing Future<int Function()?>\n");
1583 THR_Print(
"********************************************************\n\n");
1605 RunTTSTest(type_future, {obj_futurenullablefunction, tav_null, tav_null});
1607 {obj_futurenullablefunction, tav_null, tav_null});
1609 {obj_futurenullablefunction, tav_null, tav_null});
1611 {obj_futurefunction, tav_null, tav_null});
1613 {obj_futurenullablefunction, tav_null, tav_null});
1614 RunTTSTest(type_future_t, {obj_futurenullablefunction, tav_null, tav_null});
1616 {obj_futurenullablefunction, tav_nullable_object, tav_null});
1617 RunTTSTest(type_future_t, {obj_futurenullablefunction,
1618 tav_nullable_function_int_nullary, tav_null});
1634 RunTTSTest(type_future_nullable_function_int_nullary,
1635 FalseNegative({obj_futurenullablefunction, tav_null, tav_null}));
1637 tav_nullable_function, tav_null}));
1661 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1663 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1665 tav_nullable_closure, tav_null}));
1667 Failure({obj_futurenullablefunction, tav_closure, tav_null}));
1670 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1672 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1674 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1676 Failure({obj_futurenullablefunction, tav_object, tav_null}));
1678 Failure({obj_futurenullablefunction, tav_function, tav_null}));
1680 tav_function_int_nullary, tav_null}));
1684 const char* kScript =
1687 test(x) => x as B<T>;
1692 createACint() => A<C<int>>();
1693 createBCint() => B<C<int>>();
1694 createBCnum() => B<C<num>>();
1706 dst_tav.SetTypeAt(0,
1710 const auto& cint_tav =
1715 RunTTSTest(dst_type, {bcint, cint_tav, function_tav});
1722 const char* kScript =
1725 T test(dynamic x) => x as T;
1727 H genericFun<H>(dynamic x) => x as H;
1729 createAInt() => A<int>();
1730 createAString() => A<String>();
1737 const auto& fun_generic =
1740 const auto& dst_type_t =
1743 const auto& dst_type_h =
1749 const auto& int_tav =
1751 const auto& string_tav =
1757 THR_Print(
"Testing int instance, class parameter instantiated to int\n");
1758 RunTTSTest(dst_type_t, {int_instance, int_tav, string_tav});
1759 THR_Print(
"\nTesting string instance, class parameter instantiated to int\n");
1763 "\nTesting string instance, function parameter instantiated to string\n");
1764 RunTTSTest(dst_type_h, {string_instance, int_tav, string_tav});
1771 const auto& tav_null = Object::null_type_arguments();
1776 tav_null, tav_null}));
1787 const auto& tav_null = Object::null_type_arguments();
1803 const auto& tav_null = Object::null_type_arguments();
1818 const auto& tav_null = Object::null_type_arguments();
1823 tav_null, tav_null}));
1832 const auto& type_obj =
1834 const auto& tav_null = Object::null_type_arguments();
1838 const bool should_specialize =
true;
1839 auto make_test_case = [&](
const Instance&
instance) -> TTSTestCase {
1840 return {
instance, tav_null, tav_null};
1858 const char* kScript =
1863 createG() => () => 3;
1864 createH() => (int x, String y, {int z = 0}) => x + z;
1866 createAInt() => A<int>();
1867 createAFunction() => A<Function>();
1878 RunTTSTest(type_function, {obj_f, tav_null, tav_null});
1879 RunTTSTest(type_function, {obj_g, tav_null, tav_null});
1880 RunTTSTest(type_function, {obj_h, tav_null, tav_null});
1884 const auto& obj_a_function =
1888 tav_function.SetTypeAt(0, type_function);
1893 RunTTSTest(type_a_function, {obj_a_function, tav_null, tav_null});
1898 const char* kScript =
1903 class D extends C {}
1904 class E extends D {}
1907 createBE() => B<E>();
1908 createBENullable() => B<E?>();
1909 createBNull() => B<Null>();
1910 createBNever() => B<Never>();
1920 const auto& obj_b_e_nullable =
1923 const auto& obj_b_never =
1926 const auto& tav_null = Object::null_type_arguments();
1928 tav_nullable_object.SetTypeAt(
1933 tav_object.SetTypeAt(
1946 auto& type_c_nullable =
1951 tav_e.SetTypeAt(0, type_e);
1954 tav_d.SetTypeAt(0, type_d);
1957 tav_c.SetTypeAt(0, type_c);
1960 tav_nullable_c.SetTypeAt(0, type_c_nullable);
1969 const auto& type_a =
1972 tav_a.SetTypeAt(0, type_a);
1980 TTSTestCase b_e_testcase{obj_b_e, tav_null, tav_e};
1982 TTSTestCase b_d_testcase{obj_b_e, tav_null, tav_d};
1983 TTSTestCase b_c_testcase{obj_b_e, tav_null, tav_c};
1986 state.InvokeLazilySpecializedStub(b_e_testcase);
1987 state.InvokeExistingStub(b_e_testcase);
1993 state.InvokeLazilySpecializedStub(b_d_testcase);
1999 state.InvokeExistingStub(b_e_testcase);
2002 state.InvokeExistingStub(b_e_testcase);
2004 state.InvokeExistingStub({obj_b_never, tav_null, tav_d});
2005 state.InvokeExistingStub({obj_b_null, tav_null, tav_nullable_c});
2006 state.InvokeExistingStub(
Failure({obj_b_null, tav_null, tav_c}));
2008 state.InvokeExistingStub({obj_b_e, tav_null, tav_nullable_object});
2009 state.InvokeExistingStub({obj_b_e_nullable, tav_null, tav_nullable_object});
2010 state.InvokeExistingStub({obj_b_e, tav_null, tav_object});
2011 state.InvokeExistingStub(
Failure({obj_b_e_nullable, tav_null, tav_object}));
2015#define FILE_RESOLVE_URI(Uri) "file:///" Uri
2016#define FIRST_PARTIAL_LIBRARY_NAME "test-lib"
2017#define SECOND_PARTIAL_LIBRARY_NAME "test-lib-2"
2018#define THIRD_PARTIAL_LIBRARY_NAME "test-lib-3"
2021 const char* kFirstScript =
2024 createB() => B<int>();
2029 const char* kSecondScript =
2032 class B2<T> extends B<T> {}
2033 createB2() => B2<int>();
2037 const char* kThirdScript =
2040 class B3<T> extends B<T> {}
2041 createB3() => B3<int>();
2048#undef THIRD_PARTIAL_LIBRARY_URI
2049#undef SECOND_PARTIAL_LIBRARY_URI
2050#undef FIRST_PARTIAL_LIBRARY_URI
2051#undef FILE_RESOLVE_URI
2053 THR_Print(
"------------------------------------------------------\n");
2055 THR_Print(
"------------------------------------------------------\n");
2062 const auto& tav_null = Object::null_type_arguments();
2072 TTSTestState
state(thread, type_b2_t);
2074 TTSTestCase first_positive{obj_b, tav_int, tav_null};
2075 TTSTestCase first_false_negative = {obj_b, tav_num, tav_null};
2077 ASSERT(!first_false_negative.HasSameSTCEntry(first_positive));
2080 state.TypeToTest(first_false_negative));
2082 state.InvokeLazilySpecializedStub(first_false_negative);
2084 state.InvokeEagerlySpecializedStub(
STCCheck(first_false_negative));
2086 state.InvokeExistingStub(first_positive);
2091 THR_Print(
"------------------------------------------------------\n");
2093 THR_Print(
"------------------------------------------------------\n");
2100 EXPECT((
state.last_stc().IsNull() && stc_cache.IsNull()) ||
2101 stc_cache.ptr() ==
state.last_stc().cache());
2105 TTSTestCase second_positive{obj_b2, tav_int, tav_null};
2106 TTSTestCase second_false_negative = {obj_b2, tav_num, tav_null};
2108 ASSERT(!second_positive.HasSameSTCEntry(second_false_negative));
2109 ASSERT(!second_positive.HasSameSTCEntry(first_positive));
2110 ASSERT(!second_positive.HasSameSTCEntry(first_false_negative));
2111 ASSERT(!second_false_negative.HasSameSTCEntry(first_positive));
2112 ASSERT(!second_false_negative.HasSameSTCEntry(first_false_negative));
2115 state.TypeToTest(second_false_negative));
2116 ASSERT(
state.TypeToTest(first_positive) ==
state.TypeToTest(second_positive));
2119 state.InvokeExistingStub(first_positive);
2134 state.InvokeExistingStub(first_positive);
2135 state.InvokeExistingStub(second_positive);
2142 THR_Print(
"------------------------------------------------------\n");
2144 THR_Print(
"------------------------------------------------------\n");
2151 EXPECT((
state.last_stc().IsNull() && stc_cache.IsNull()) ||
2152 stc_cache.ptr() ==
state.last_stc().cache());
2156 TTSTestCase third_positive{obj_b3, tav_int, tav_null};
2157 TTSTestCase third_false_negative = {obj_b3, tav_num, tav_null};
2159 ASSERT(!third_positive.HasSameSTCEntry(third_false_negative));
2160 ASSERT(!third_positive.HasSameSTCEntry(first_positive));
2161 ASSERT(!third_positive.HasSameSTCEntry(first_false_negative));
2162 ASSERT(!third_positive.HasSameSTCEntry(second_positive));
2163 ASSERT(!third_positive.HasSameSTCEntry(second_false_negative));
2164 ASSERT(!third_false_negative.HasSameSTCEntry(first_positive));
2165 ASSERT(!third_false_negative.HasSameSTCEntry(first_false_negative));
2166 ASSERT(!third_false_negative.HasSameSTCEntry(second_positive));
2167 ASSERT(!third_false_negative.HasSameSTCEntry(second_false_negative));
2170 state.TypeToTest(third_false_negative));
2171 ASSERT(
state.TypeToTest(first_positive) ==
state.TypeToTest(third_positive));
2175 state.InvokeExistingStub(first_positive);
2176 state.InvokeExistingStub(second_positive);
2185 state.InvokeExistingStub(third_positive);
2186 state.InvokeExistingStub(second_positive);
2187 state.InvokeExistingStub(first_positive);
2199#if !defined(PRODUCT)
2200static const char* kLoadedScript =
2204 createAInt() => A<int>();
2205 createAString() => A<String>();
2207 (int, int) createRecordIntInt() => (1, 2);
2208 (String, int) createRecordStringInt() => ("foo", 2);
2209 (int, String) createRecordIntString() => (1, "bar");
2212static const char* kReloadedScript =
2215 class A2<T> extends A<T> {}
2217 createAInt() => A<int>();
2218 createAString() => A<String>();
2219 createA2Int() => A2<int>();
2220 createA2String() => A2<String>();
2222 (int, int) createRecordIntInt() => (1, 2);
2223 (String, int) createRecordStringInt() => ("foo", 2);
2224 (int, String) createRecordIntString() => (1, "bar");
2228 auto*
const zone = thread->zone();
2237 const auto& record_int_int =
2238 Instance::CheckedHandle(zone,
Invoke(root_library,
"createRecordIntInt"));
2239 const auto& record_int_string = Instance::CheckedHandle(
2240 zone,
Invoke(root_library,
"createRecordIntString"));
2241 const auto& record_string_int = Instance::CheckedHandle(
2242 zone,
Invoke(root_library,
"createRecordStringInt"));
2244 const auto& tav_null = Object::null_type_arguments();
2245 const auto& tav_int =
2254 auto& type_record_int_int =
2258 TTSTestState
state(thread, type_a_int);
2259 state.InvokeLazilySpecializedStub({aint, tav_null, tav_null});
2260 state.InvokeExistingStub(
Failure({astring, tav_null, tav_null}));
2262 TTSTestState record_state(thread, type_record_int_int);
2263 record_state.InvokeLazilySpecializedStub(
2264 {record_int_int, tav_null, tav_null});
2265 record_state.InvokeExistingStub(
2266 Failure({record_string_int, tav_null, tav_null}));
2267 record_state.InvokeExistingStub(
2268 Failure({record_int_string, tav_null, tav_null}));
2271 EXPECT(type_a_int.type_test_stub() !=
2273 EXPECT(type_record_int_int.type_test_stub() !=
2282 EXPECT(type_a_int.type_test_stub() ==
2284 EXPECT(type_record_int_int.type_test_stub() ==
2288 (
state.current_stc() ==
state.last_stc().ptr() &&
2289 state.last_stc().NumberOfChecks() == 0));
2291 (record_state.current_stc() == record_state.last_stc().ptr() &&
2292 record_state.last_stc().NumberOfChecks() == 0));
2295 state.InvokeExistingStub(
Failure({astring, tav_null, tav_null}));
2296 state.InvokeExistingStub({a2int, tav_null, tav_null});
2297 state.InvokeExistingStub(
Failure({a2string, tav_null, tav_null}));
2299 record_state.InvokeExistingStub(
2301 record_state.InvokeExistingStub(
2302 Failure({record_string_int, tav_null, tav_null}));
2303 record_state.InvokeExistingStub(
2304 Failure({record_int_string, tav_null, tav_null}));
2315 const auto& tav_null = Object::null_type_arguments();
2316 const auto& tav_int =
2318 const auto& tav_string =
2325 const auto& type_a_t =
Type::Handle(class_a.DeclarationType());
2326 TTSTestCase positive1{aint, tav_int, tav_null};
2327 TTSTestCase positive2{astring, tav_string, tav_null};
2328 TTSTestCase negative1 =
Failure({astring, tav_int, tav_null});
2329 TTSTestCase negative2 =
Failure({aint, tav_string, tav_null});
2330 TTSTestCase false_negative =
FalseNegative({aint, tav_num, tav_null});
2331 TTSTestState
state(thread, type_a_t);
2332 state.InvokeLazilySpecializedStub(positive1);
2333 state.InvokeExistingStub(positive2);
2334 state.InvokeExistingStub(negative1);
2335 state.InvokeExistingStub(negative2);
2336 state.InvokeExistingStub(false_negative);
2344 EXPECT(type_a_t.type_test_stub() ==
2348 (
state.current_stc() ==
state.last_stc().ptr() &&
2349 state.last_stc().NumberOfChecks() == 0));
2352 state.InvokeExistingStub(positive2);
2353 state.InvokeExistingStub(negative1);
2354 state.InvokeExistingStub(negative2);
2355 state.InvokeExistingStub(false_negative);
2356 state.InvokeExistingStub({a2int, tav_int, tav_null});
2357 state.InvokeExistingStub({a2string, tav_string, tav_null});
2358 state.InvokeExistingStub(
Failure({a2string, tav_int, tav_null}));
2359 state.InvokeExistingStub(
Failure({a2int, tav_string, tav_null}));
2410 const intptr_t kNumUnrelated = class_table->
NumCids() - 1;
2413 abstract class B<X> {}
2414 class G<Y> implements B<Y> {}
2415 class C implements B<int> {}
2416 class D implements B<int> {}
2418 for (intptr_t
i = 0;
i < kNumUnrelated;
i++) {
2420 class U%)" Pd R"( {}
2425 class I implements B<String> {
2441 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
2446 EXPECT_EQ(kNumUnrelated, class_b.id() - 1);
2447 EXPECT_EQ(class_b.id() + 1, class_g.id());
2448 EXPECT_EQ(class_c.id() + 1, class_d.id());
2449 EXPECT_EQ(class_d.id() + 1, class_u0.id());
2450 EXPECT_EQ(class_u0.id() + kNumUnrelated, class_i.id());
2451 EXPECT_EQ(class_g.id(), class_i.id() - class_c.id());
2453 const auto& tav_null = Object::null_type_arguments();
2461 TTSTestState
state(thread, type_b_int);
2462 state.InvokeEagerlySpecializedStub(
Failure({obj_i, tav_null, tav_null}));
2465struct STCTestResults {
2466 bool became_hash_cache =
false;
2467 bool cache_capped =
false;
2471 intptr_t num_classes) {
2473 buffer.AddString(
"class D<S> {}\n");
2474 buffer.AddString(
"D<int> Function() createClosureD() => () => D<int>();\n");
2475 for (intptr_t
i = 0;
i < num_classes;
i++) {
2476 buffer.Printf(R
"(class C%)" Pd R"(<S> extends D<S> {}
2477 C%)" Pd R"(<int> Function() createClosureC%)" Pd R"(() => () => C%)" Pd
2489 TransitionNativeToVM transition(thread);
2490 Zone*
const zone = thread->zone();
2492 const auto& root_lib =
2494 EXPECT(!root_lib.IsNull());
2497 ASSERT(!class_d.IsNull());
2499 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
2502 const auto& object_d =
2503 Instance::CheckedHandle(zone,
Invoke(root_lib,
"createClosureD"));
2504 ASSERT(!object_d.IsNull());
2505 auto& type_closure_d_int =
2509 const auto& tav_null = Object::null_type_arguments();
2511 TTSTestState
state(thread, type_closure_d_int);
2513 state.InvokeEagerlySpecializedStub(
2514 {Object::null_object(), tav_null, tav_null, can_be_null ?
kTTS :
kFail});
2518 STCTestResults results;
2519 for (intptr_t
i = 0;
i < num_classes; ++
i) {
2522 ASSERT(!class_c.IsNull());
2524 SafepointWriteRwLocker ml(thread,
2525 thread->isolate_group()->program_lock());
2531 TTSTestCase base_case = {object_c, tav_null, tav_null};
2533 if (
i >= FLAG_max_subtype_cache_entries) {
2535 FLAG_max_subtype_cache_entries);
2539 results.cache_capped =
true;
2541 const bool was_hash =
state.last_stc().IsHash();
2547 }
else if (was_hash) {
2550 }
else if (
state.last_stc().IsHash()) {
2551 results.became_hash_cache =
true;
2562 const intptr_t num_classes =
2563 Utils::Minimum(
static_cast<intptr_t
>(FLAG_max_subtype_cache_entries),
2567 EXPECT(!results.became_hash_cache);
2568 EXPECT(!results.cache_capped);
2573 const intptr_t num_classes =
2574 Utils::Minimum(
static_cast<intptr_t
>(FLAG_max_subtype_cache_entries),
2578 EXPECT(results.became_hash_cache);
2579 EXPECT(!results.cache_capped);
2585 const intptr_t num_classes = 1.1 * FLAG_max_subtype_cache_entries;
2589 results.became_hash_cache);
2590 EXPECT(results.cache_capped);
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
#define ASSERT_EQUAL(expected, actual)
#define RELEASE_ASSERT(cond)
void SetTypeTestingStub(const Code &stub) const
CodePtr type_test_stub() const
static ObjectPtr UnwrapHandle(Dart_Handle object)
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
ObjectPtr At(intptr_t index) const
void SetAt(intptr_t index, const Object &value) const
static constexpr Register kReturnReg
static AbstractTypePtr FinalizeType(const AbstractType &type, FinalizationKind finalization=kCanonicalize)
static void FinalizeTypesInClass(const Class &cls)
static void FinalizeClass(const Class &cls)
static CodePtr FinalizeCodeAndNotify(const Function &function, FlowGraphCompiler *compiler, compiler::Assembler *assembler, PoolAttachment pool_attachment, bool optimized=false, CodeStatistics *stats=nullptr)
static void DisassembleStub(const char *name, const Code &code)
static DoublePtr New(double d, Heap::Space space=Heap::kNew)
static ExceptionHandlersPtr New(intptr_t num_handlers)
static void GenerateIndirectTTSCall(compiler::Assembler *assembler, Register reg_with_type, intptr_t sub_type_cache_index)
static FunctionTypePtr New(intptr_t num_parent_type_arguments=0, Nullability nullability=Nullability::kNonNullable, Heap::Space space=Heap::kOld)
static FunctionPtr New(const FunctionType &signature, const String &name, UntaggedFunction::Kind kind, bool is_static, bool is_const, bool is_abstract, bool is_external, bool is_native, const Object &owner, TokenPosition token_pos, Heap::Space space=Heap::kOld)
static bool NullIsAssignableTo(const AbstractType &other)
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
static IsolateGroup * Current()
ClassTable * class_table() const
Mutex * subtype_test_cache_mutex()
static char * SCreate(Zone *zone, const char *format,...) PRINTF_ATTRIBUTE(2
ObjectPtr ObjectAt(intptr_t index) const
void SetObjectAt(intptr_t index, const Object &obj) const
static ObjectPoolPtr NewFromBuilder(const compiler::ObjectPoolBuilder &builder)
intptr_t GetClassId() const
virtual const char * ToCString() const
static ObjectPtr RawCast(ObjectPtr obj)
static const char * RegisterName(Register reg)
static SmiPtr New(intptr_t value)
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
static const char * NameOfStub(uword entry_point)
SubtypeTestCachePtr Copy(Thread *thread) const
intptr_t NumberOfChecks() const
static constexpr intptr_t kMaxLinearCacheEntries
void WriteToBuffer(Zone *zone, BaseTextBuffer *buffer, const char *line_prefix=nullptr) const
static const String & Empty()
static StringPtr New(Thread *thread, const char *cstr)
TTSTestState(Thread *thread, const AbstractType &type)
AbstractTypePtr TypeToTest(const TTSTestCase &test_case) const
const SubtypeTestCachePtr current_stc() const
void InvokeLazilySpecializedStub(const TTSTestCase &test_case, bool should_specialize=true)
void InvokeExistingStub(const TTSTestCase &test_case)
const SubtypeTestCache & last_stc() const
void InvokeEagerlySpecializedStub(const TTSTestCase &test_case)
static Dart_Handle LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri=RESOLVED_USER_TEST_URI, bool finalize=true, bool allow_compile_errors=false)
static Thread * Current()
IsolateGroup * isolate_group() const
~TraceStubInvocationScope()
TraceStubInvocationScope()
TypeArgumentsPtr Canonicalize(Thread *thread) const
static TypeArgumentsPtr New(intptr_t len, Heap::Space space=Heap::kOld)
static CodePtr DefaultCodeForType(const AbstractType &type, bool lazy_specialize=true)
static CodePtr SpecializeStubFor(Thread *thread, const AbstractType &type)
static TypePtr StringType()
static TypePtr DartFunctionType()
static TypePtr ObjectType()
static TypePtr DynamicType()
static TypePtr New(const Class &clazz, const TypeArguments &arguments, Nullability nullability=Nullability::kNonNullable, Heap::Space space=Heap::kOld)
static T Minimum(T x, T y)
static word element_offset(intptr_t index)
#define THR_Print(format,...)
struct _Dart_Handle * Dart_Handle
#define FAIL(name, result)
const uint8_t uint32_t uint32_t GError ** error
Dart_NativeFunction function
static constexpr intptr_t kWordSize
constexpr int64_t kMaxInt64
static TTSTestCase FalseNegative(const TTSTestCase &original)
LibraryPtr LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri)
const char * kSubtypeRangeCheckScript
static void FinalizeAndCanonicalize(AbstractType *type)
const char *const class_name
const char * kRecordSubtypeRangeCheckScript
ObjectPtr Invoke(const Library &lib, const char *name)
FunctionPtr GetFunction(const Library &lib, const char *name)
LibraryPtr ReloadTestScript(const char *script)
static const char * kTestResultStrings[]
static TTSTestCase Respecialization(const TTSTestCase &original)
static void SubtypeTestCacheTest(Thread *thread, intptr_t num_classes, bool expect_hash)
static void GenerateInvokeTTSStub(compiler::Assembler *assembler)
static TTSTestCase STCCheck(const TTSTestCase &original)
static constexpr int kCallerSpSlotFromFp
ISOLATE_UNIT_TEST_CASE(StackAllocatedDestruction)
constexpr RegList kDartAvailableCpuRegs
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")
ClassPtr GetClass(const Library &lib, const char *name)
TEST_CASE(DirectoryCurrent)
TypeParameterPtr GetClassTypeParameter(const Class &klass, intptr_t index)
static void RunTTSTest(const AbstractType &dst_type, const TTSTestCase &test_case, bool should_specialize=true)
void SetupCoreLibrariesForUnitTest()
TypeParameterPtr GetFunctionTypeParameter(const Function &fun, intptr_t index)
static TTSTestCase Failure(const TTSTestCase &original)
const char *const function_name
static TTSTestCase RuntimeCheck(const TTSTestCase &original)
static void CanonicalizeTAV(TypeArguments *tav)
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 Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
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
std::function< void()> closure
static bool Bind(PassBindingsCacheMTL &pass, ShaderStage stage, size_t bind_index, const BufferView &view)
static constexpr intptr_t kInternalRegisters
const TTSTestResult expected_result
bool HasSTCEntry(const SubtypeTestCache &cache, const AbstractType &dst_type, Bool *out_result=nullptr, intptr_t *out_index=nullptr) const
TTSTestCase(const Object &obj, const TypeArguments &i_tav, const TypeArguments &f_tav, const TTSTestResult result=kTTS)
bool HasSameSTCEntry(const TTSTestCase &other) const
const TypeArguments & function_tav
bool ShouldEnterRuntime() const
const TypeArguments & instantiator_tav
static constexpr Register kDstTypeReg
static constexpr Register kInstanceReg
static constexpr Register kFunctionTypeArgumentsReg
static constexpr Register kInstantiatorTypeArgumentsReg
static constexpr intptr_t kPreservedAbiRegisters
static constexpr Register kScratchReg
static constexpr intptr_t kAbiRegisters
#define FILE_RESOLVE_URI(Uri)
#define THIRD_PARTIAL_LIBRARY_NAME
#define FIRST_PARTIAL_LIBRARY_NAME
#define SECOND_PARTIAL_LIBRARY_NAME
#define EXPECT_VALID(handle)