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);
162 compiler::target::Array::element_offset(0));
171 __ CompareImmediate(reg, calculate_breadcrumb(reg));
180 compiler::target::Array::element_offset(0));
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");
299 const auto& closure = Closure::Cast(
instance);
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;
332 const auto& closure = Closure::Cast(
instance);
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,
515 last_tested_type_.ToCString());
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()) {
710 previous_stc_.
IsNull() ? 1 : previous_stc_.NumberOfChecks() + 1,
711 last_stc_.NumberOfChecks());
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});
969 type_nullable_int = type_nullable_int.ToNullability(
973 tav_nullable_int.SetTypeAt(0, type_nullable_int);
975 auto& type_base_nullable_int =
978 RunTTSTest(type_base_nullable_int, {obj_base_null, tav_null, tav_null});
979 RunTTSTest(type_base_nullable_int, {obj_base_never, tav_null, tav_null});
986 tav_int.SetTypeAt(0, type_int);
993 RunTTSTest(type_base_int, {obj_base_never, tav_null, tav_null});
999 RunTTSTest(type_i2, {obj_i2, tav_null, tav_null});
1002 RunTTSTest(type_i2, {obj_a1, tav_null, tav_null});
1005 RunTTSTest(type_i2, {obj_b1, tav_null, tav_null});
1009 auto& type_i_object_dynamic =
1012 RunTTSTest(type_i_object_dynamic, {obj_i, tav_null, tav_null});
1015 Failure({obj_base_int, tav_null, tav_null}));
1018 RunTTSTest(type_i_object_dynamic, {obj_a2, tav_null, tav_null});
1021 RunTTSTest(type_i_object_dynamic, {obj_b2, tav_null, tav_null});
1030 auto& type_dynamic_t =
1033 RunTTSTest(type_dynamic_t, {obj_i, tav_object, tav_null});
1038 RunTTSTest(type_dynamic_t, {obj_a2, tav_object, tav_null});
1045 auto& type_non_nullable_object =
1046 Type::Handle(isolate_group->object_store()->non_nullable_object_type());
1047 RunTTSTest(type_non_nullable_object, {obj_a, tav_null, tav_null});
1051 const auto& root_library =
1057 const auto& fun_generic =
1062 const auto& obj_base_int =
1070 const auto& obj_basea2int =
1072 const auto& obj_basea2a1 =
1074 const auto& obj_baseb2int =
1076 const auto& obj_baseistringdouble =
1089 type_object = type_object.ToNullability(
1092 auto& type_a1 =
Type::Handle(class_a1.DeclarationType());
1101 tav_object_dynamic.SetTypeAt(0, type_object);
1102 tav_object_dynamic.SetTypeAt(1, type_dynamic);
1106 tav_dynamic_int.SetTypeAt(0, type_dynamic);
1107 tav_dynamic_int.SetTypeAt(1, type_int);
1111 tav_dynamic_string.SetTypeAt(0, type_dynamic);
1112 tav_dynamic_string.SetTypeAt(1, type_string);
1116 tav_int.SetTypeAt(0, type_int);
1119 auto& type_i_object_dynamic =
1123 tav_iod.SetTypeAt(0, type_i_object_dynamic);
1138 auto& type_base_i_object_dynamic =
1141 RunTTSTest(type_base_i_object_dynamic, {obj_baseb2int, tav_null, tav_null});
1143 {obj_baseistringdouble, tav_null, tav_null});
1153 tav_baset.SetTypeAt(
1157 RunTTSTest(type_base_t, {obj_base_int, tav_int, tav_null});
1162 tav_baseb.SetTypeAt(
1167 RunTTSTest(type_base_b, {obj_base_int, tav_null, tav_dynamic_int});
1169 Failure({obj_baseistringdouble, tav_null, tav_dynamic_int}));
1171 RunTTSTest(type_base_b, {obj_base_int, tav_null, tav_null});
1186 auto& type_i_dynamic_string =
1188 type_i_dynamic_string = type_i_dynamic_string.ToNullability(
1191 RunTTSTest(type_i_dynamic_string, {obj_i, tav_null, tav_null});
1193 Failure({obj_base_int, tav_null, tav_null}));
1203 tav_a2_t.SetTypeAt(0, type_a2_t);
1214 tav_a1.SetTypeAt(0, type_a1);
1219 tav_a2_a1.SetTypeAt(0, type_a2_a1);
1232 class B extends A {}
1233 class C implements A {}
1237 getRecordType1() => getType<(int, A)>();
1238 getRecordType2() => getType<(A, int, String)>();
1239 getRecordType3() => getType<(int, D)>();
1241 createObj1() => (1, B());
1242 createObj2() => (1, 'bye');
1243 createObj3() => (1, foo: B());
1244 createObj4() => (1, B(), 2);
1245 createObj5() => (C(), 2, 'hi');
1246 createObj6() => (D(), 2, 'hi');
1247 createObj7() => (3, D<int>());
1248 createObj8() => (D<int>(), 3);
1252 const auto& root_library =
1255 const auto& type1 = AbstractType::Cast(
1257 const auto& type2 = AbstractType::Cast(
1259 const auto& type3 = AbstractType::Cast(
1277 RunTTSTest(type1, {obj1, tav_null, tav_null});
1284 RunTTSTest(type2, {obj5, tav_null, tav_null});
1289 RunTTSTest(type3, {obj7, tav_null, tav_null});
1294 const char* kScript =
1296 abstract class I<T> {}
1297 class B<R> implements I<String> {}
1299 createBInt() => B<int>();
1306 const auto& tav_null = Object::null_type_arguments();
1313 const auto& type_i_t =
Type::Handle(class_i.DeclarationType());
1315 RunTTSTest(type_i_string, {obj_b_int, tav_null, tav_null});
1323 const char* kScript =
1325 import "dart:async";
1327 Future<int> createFutureInt() async => 3;
1328 Future<int Function()> createFutureFunction() async => () => 3;
1329 Future<int Function()?> createFutureNullableFunction() async =>
1330 (() => 3) as int Function()?;
1335 const auto& class_future =
1339 const auto& class_closure =
1341 const auto& obj_futureint =
1343 const auto& obj_futurefunction =
1345 const auto& obj_futurenullablefunction =
1348 const auto& tav_null = Object::null_type_arguments();
1367 tav_dynamic.SetTypeAt(0, Object::dynamic_type());
1370 tav_object.SetTypeAt(0, type_object);
1373 tav_legacy_object.SetTypeAt(0, type_legacy_object);
1376 tav_nullable_object.SetTypeAt(0, type_nullable_object);
1379 tav_int.SetTypeAt(0, type_int);
1382 tav_num.SetTypeAt(0, type_num);
1385 tav_string.SetTypeAt(0, type_string);
1403 auto& type_future_int =
1409 auto& type_future_num =
1412 const auto& type_future_t =
Type::Handle(class_future.DeclarationType());
1414 THR_Print(
"********************************************************\n");
1416 THR_Print(
"********************************************************\n\n");
1433 RunTTSTest(type_future, {obj_futureint, tav_null, tav_null});
1434 RunTTSTest(type_future_dynamic, {obj_futureint, tav_null, tav_null});
1435 RunTTSTest(type_future_object, {obj_futureint, tav_null, tav_null});
1436 RunTTSTest(type_future_legacy_object, {obj_futureint, tav_null, tav_null});
1437 RunTTSTest(type_future_nullable_object, {obj_futureint, tav_null, tav_null});
1438 RunTTSTest(type_future_int, {obj_futureint, tav_null, tav_null});
1439 RunTTSTest(type_future_num, {obj_futureint, tav_null, tav_null});
1440 RunTTSTest(type_future_t, {obj_futureint, tav_int, tav_null});
1474 auto& type_function_int_nullary =
1478 type_function_int_nullary.set_num_implicit_parameters(1);
1479 type_function_int_nullary.set_num_fixed_parameters(1);
1481 type_function_int_nullary.SetParameterTypeAt(0, Type::dynamic_type());
1482 type_function_int_nullary.set_result_type(type_int);
1484 auto& type_legacy_function_int_nullary =
1488 auto& type_nullable_function_int_nullary =
1494 tav_function.SetTypeAt(0, type_function);
1497 tav_legacy_function.SetTypeAt(0, type_legacy_function);
1500 tav_nullable_function.SetTypeAt(0, type_nullable_function);
1503 tav_closure.SetTypeAt(0, type_closure);
1506 tav_legacy_closure.SetTypeAt(0, type_legacy_closure);
1509 tav_nullable_closure.SetTypeAt(0, type_nullable_closure);
1512 tav_function_int_nullary.SetTypeAt(0, type_function_int_nullary);
1514 auto& tav_legacy_function_int_nullary =
1516 tav_legacy_function_int_nullary.SetTypeAt(0,
1517 type_legacy_function_int_nullary);
1519 auto& tav_nullable_function_int_nullary =
1521 tav_nullable_function_int_nullary.SetTypeAt(
1522 0, type_nullable_function_int_nullary);
1543 auto& type_future_function_int_nullary =
1546 auto& type_future_legacy_function_int_nullary =
1549 auto& type_future_nullable_function_int_nullary =
1553 THR_Print(
"\n********************************************************\n");
1554 THR_Print(
" Testing Future<int Function()>\n");
1555 THR_Print(
"********************************************************\n\n");
1577 RunTTSTest(type_future, {obj_futurefunction, tav_null, tav_null});
1578 RunTTSTest(type_future_dynamic, {obj_futurefunction, tav_null, tav_null});
1580 {obj_futurefunction, tav_null, tav_null});
1582 {obj_futurefunction, tav_null, tav_null});
1583 RunTTSTest(type_future_object, {obj_futurefunction, tav_null, tav_null});
1585 {obj_futurefunction, tav_null, tav_null});
1587 {obj_futurefunction, tav_null, tav_null});
1588 RunTTSTest(type_future_object, {obj_futurefunction, tav_null, tav_null});
1590 {obj_futurefunction, tav_null, tav_null});
1592 {obj_futurefunction, tav_null, tav_null});
1593 RunTTSTest(type_future_function, {obj_futurefunction, tav_null, tav_null});
1594 RunTTSTest(type_future_t, {obj_futurefunction, tav_null, tav_null});
1596 {obj_futurefunction, tav_nullable_object, tav_null});
1597 RunTTSTest(type_future_t, {obj_futurefunction, tav_legacy_object, tav_null});
1598 RunTTSTest(type_future_t, {obj_futurefunction, tav_object, tav_null});
1600 {obj_futurefunction, tav_function_int_nullary, tav_null});
1613 RunTTSTest(type_future_nullable_function_int_nullary,
1615 RunTTSTest(type_future_legacy_function_int_nullary,
1620 tav_nullable_function, tav_null}));
1622 tav_legacy_function, tav_null}));
1624 FalseNegative({obj_futurefunction, tav_function, tav_null}));
1627 tav_nullable_function_int_nullary, tav_null}));
1629 FalseNegative({obj_futurefunction, tav_legacy_function_int_nullary,
1642 Failure({obj_futurefunction, tav_null, tav_null}));
1644 Failure({obj_futurefunction, tav_null, tav_null}));
1646 Failure({obj_futurefunction, tav_null, tav_null}));
1648 Failure({obj_futurefunction, tav_nullable_closure, tav_null}));
1650 Failure({obj_futurefunction, tav_legacy_closure, tav_null}));
1652 Failure({obj_futurefunction, tav_closure, tav_null}));
1654 THR_Print(
"\n********************************************************\n");
1655 THR_Print(
" Testing Future<int Function()?>\n");
1656 THR_Print(
"********************************************************\n\n");
1678 RunTTSTest(type_future, {obj_futurenullablefunction, tav_null, tav_null});
1680 {obj_futurenullablefunction, tav_null, tav_null});
1682 {obj_futurenullablefunction, tav_null, tav_null});
1684 {obj_futurenullablefunction, tav_null, tav_null});
1686 {obj_futurefunction, tav_null, tav_null});
1688 {obj_futurenullablefunction, tav_null, tav_null});
1690 {obj_futurenullablefunction, tav_null, tav_null});
1692 {obj_futurenullablefunction, tav_null, tav_null});
1693 RunTTSTest(type_future_t, {obj_futurenullablefunction, tav_null, tav_null});
1695 {obj_futurenullablefunction, tav_nullable_object, tav_null});
1697 {obj_futurenullablefunction, tav_legacy_object, tav_null});
1698 RunTTSTest(type_future_t, {obj_futurenullablefunction,
1699 tav_nullable_function_int_nullary, tav_null});
1715 RunTTSTest(type_future_nullable_function_int_nullary,
1716 FalseNegative({obj_futurenullablefunction, tav_null, tav_null}));
1717 RunTTSTest(type_future_legacy_function_int_nullary,
1718 FalseNegative({obj_futurenullablefunction, tav_null, tav_null}));
1720 tav_nullable_function, tav_null}));
1722 tav_legacy_function, tav_null}));
1725 tav_legacy_function_int_nullary, tav_null}));
1749 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1751 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1753 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1755 tav_nullable_closure, tav_null}));
1757 tav_legacy_closure, tav_null}));
1759 Failure({obj_futurenullablefunction, tav_closure, tav_null}));
1762 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1764 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1766 Failure({obj_futurenullablefunction, tav_null, tav_null}));
1768 Failure({obj_futurenullablefunction, tav_object, tav_null}));
1770 Failure({obj_futurenullablefunction, tav_function, tav_null}));
1772 tav_function_int_nullary, tav_null}));
1776 const char* kScript =
1779 test(x) => x as B<T>;
1784 createACint() => A<C<int>>();
1785 createBCint() => B<C<int>>();
1786 createBCnum() => B<C<num>>();
1798 dst_tav.SetTypeAt(0,
1802 const auto& cint_tav =
1807 RunTTSTest(dst_type, {bcint, cint_tav, function_tav});
1814 const char* kScript =
1817 T test(dynamic x) => x as T;
1819 H genericFun<H>(dynamic x) => x as H;
1821 createAInt() => A<int>();
1822 createAString() => A<String>();
1829 const auto& fun_generic =
1832 const auto& dst_type_t =
1835 const auto& dst_type_h =
1841 const auto& int_tav =
1843 const auto& string_tav =
1849 THR_Print(
"Testing int instance, class parameter instantiated to int\n");
1850 RunTTSTest(dst_type_t, {int_instance, int_tav, string_tav});
1851 THR_Print(
"\nTesting string instance, class parameter instantiated to int\n");
1855 "\nTesting string instance, function parameter instantiated to string\n");
1856 RunTTSTest(dst_type_h, {string_instance, int_tav, string_tav});
1863 const auto& tav_null = Object::null_type_arguments();
1868 tav_null, tav_null}));
1879 const auto& tav_null = Object::null_type_arguments();
1895 const auto& tav_null = Object::null_type_arguments();
1910 const auto& tav_null = Object::null_type_arguments();
1915 tav_null, tav_null}));
1924 const auto& type_obj =
1926 const auto& tav_null = Object::null_type_arguments();
1930 const bool should_specialize =
true;
1931 auto make_test_case = [&](
const Instance&
instance) -> TTSTestCase {
1932 return {
instance, tav_null, tav_null};
1950 const char* kScript =
1955 createG() => () => 3;
1956 createH() => (int x, String y, {int z = 0}) => x + z;
1958 createAInt() => A<int>();
1959 createAFunction() => A<Function>();
1970 RunTTSTest(type_function, {obj_f, tav_null, tav_null});
1971 RunTTSTest(type_function, {obj_g, tav_null, tav_null});
1972 RunTTSTest(type_function, {obj_h, tav_null, tav_null});
1976 const auto& obj_a_function =
1980 tav_function.SetTypeAt(0, type_function);
1985 RunTTSTest(type_a_function, {obj_a_function, tav_null, tav_null});
1990 const char* kScript =
1995 class D extends C {}
1996 class E extends D {}
1999 createBE() => B<E>();
2000 createBENullable() => B<E?>();
2001 createBNull() => B<Null>();
2002 createBNever() => B<Never>();
2012 const auto& obj_b_e_nullable =
2015 const auto& obj_b_never =
2018 const auto& tav_null = Object::null_type_arguments();
2020 tav_nullable_object.SetTypeAt(
2025 tav_legacy_object.SetTypeAt(
2030 tav_object.SetTypeAt(
2043 auto& type_c_nullable =
2046 auto& type_c_legacy =
2051 tav_e.SetTypeAt(0, type_e);
2054 tav_d.SetTypeAt(0, type_d);
2057 tav_c.SetTypeAt(0, type_c);
2060 tav_nullable_c.SetTypeAt(0, type_c_nullable);
2063 tav_legacy_c.SetTypeAt(0, type_c_legacy);
2072 const auto& type_a =
2075 tav_a.SetTypeAt(0, type_a);
2083 TTSTestCase b_e_testcase{obj_b_e, tav_null, tav_e};
2085 TTSTestCase b_d_testcase{obj_b_e, tav_null, tav_d};
2086 TTSTestCase b_c_testcase{obj_b_e, tav_null, tav_c};
2089 state.InvokeLazilySpecializedStub(b_e_testcase);
2090 state.InvokeExistingStub(b_e_testcase);
2096 state.InvokeLazilySpecializedStub(b_d_testcase);
2102 state.InvokeExistingStub(b_e_testcase);
2105 state.InvokeExistingStub(b_e_testcase);
2107 state.InvokeExistingStub({obj_b_never, tav_null, tav_d});
2108 state.InvokeExistingStub({obj_b_null, tav_null, tav_nullable_c});
2109 state.InvokeExistingStub({obj_b_null, tav_null, tav_legacy_c});
2110 state.InvokeExistingStub(
Failure({obj_b_null, tav_null, tav_c}));
2112 state.InvokeExistingStub({obj_b_e, tav_null, tav_nullable_object});
2113 state.InvokeExistingStub({obj_b_e_nullable, tav_null, tav_nullable_object});
2114 state.InvokeExistingStub({obj_b_e, tav_null, tav_legacy_object});
2115 state.InvokeExistingStub({obj_b_e_nullable, tav_null, tav_legacy_object});
2116 state.InvokeExistingStub({obj_b_e, tav_null, tav_object});
2117 state.InvokeExistingStub(
Failure({obj_b_e_nullable, tav_null, tav_object}));
2121#define FILE_RESOLVE_URI(Uri) "file:///" Uri
2122#define FIRST_PARTIAL_LIBRARY_NAME "test-lib"
2123#define SECOND_PARTIAL_LIBRARY_NAME "test-lib-2"
2124#define THIRD_PARTIAL_LIBRARY_NAME "test-lib-3"
2127 const char* kFirstScript =
2130 createB() => B<int>();
2135 const char* kSecondScript =
2138 class B2<T> extends B<T> {}
2139 createB2() => B2<int>();
2143 const char* kThirdScript =
2146 class B3<T> extends B<T> {}
2147 createB3() => B3<int>();
2154#undef THIRD_PARTIAL_LIBRARY_URI
2155#undef SECOND_PARTIAL_LIBRARY_URI
2156#undef FIRST_PARTIAL_LIBRARY_URI
2157#undef FILE_RESOLVE_URI
2159 THR_Print(
"------------------------------------------------------\n");
2161 THR_Print(
"------------------------------------------------------\n");
2168 const auto& tav_null = Object::null_type_arguments();
2178 TTSTestState
state(thread, type_b2_t);
2180 TTSTestCase first_positive{obj_b, tav_int, tav_null};
2181 TTSTestCase first_false_negative = {obj_b, tav_num, tav_null};
2183 ASSERT(!first_false_negative.HasSameSTCEntry(first_positive));
2186 state.TypeToTest(first_false_negative));
2188 state.InvokeLazilySpecializedStub(first_false_negative);
2190 state.InvokeEagerlySpecializedStub(
STCCheck(first_false_negative));
2192 state.InvokeExistingStub(first_positive);
2197 THR_Print(
"------------------------------------------------------\n");
2199 THR_Print(
"------------------------------------------------------\n");
2206 EXPECT((
state.last_stc().IsNull() && stc_cache.IsNull()) ||
2207 stc_cache.ptr() ==
state.last_stc().cache());
2211 TTSTestCase second_positive{obj_b2, tav_int, tav_null};
2212 TTSTestCase second_false_negative = {obj_b2, tav_num, tav_null};
2214 ASSERT(!second_positive.HasSameSTCEntry(second_false_negative));
2215 ASSERT(!second_positive.HasSameSTCEntry(first_positive));
2216 ASSERT(!second_positive.HasSameSTCEntry(first_false_negative));
2217 ASSERT(!second_false_negative.HasSameSTCEntry(first_positive));
2218 ASSERT(!second_false_negative.HasSameSTCEntry(first_false_negative));
2221 state.TypeToTest(second_false_negative));
2222 ASSERT(
state.TypeToTest(first_positive) ==
state.TypeToTest(second_positive));
2225 state.InvokeExistingStub(first_positive);
2240 state.InvokeExistingStub(first_positive);
2241 state.InvokeExistingStub(second_positive);
2248 THR_Print(
"------------------------------------------------------\n");
2250 THR_Print(
"------------------------------------------------------\n");
2257 EXPECT((
state.last_stc().IsNull() && stc_cache.IsNull()) ||
2258 stc_cache.ptr() ==
state.last_stc().cache());
2262 TTSTestCase third_positive{obj_b3, tav_int, tav_null};
2263 TTSTestCase third_false_negative = {obj_b3, tav_num, tav_null};
2265 ASSERT(!third_positive.HasSameSTCEntry(third_false_negative));
2266 ASSERT(!third_positive.HasSameSTCEntry(first_positive));
2267 ASSERT(!third_positive.HasSameSTCEntry(first_false_negative));
2268 ASSERT(!third_positive.HasSameSTCEntry(second_positive));
2269 ASSERT(!third_positive.HasSameSTCEntry(second_false_negative));
2270 ASSERT(!third_false_negative.HasSameSTCEntry(first_positive));
2271 ASSERT(!third_false_negative.HasSameSTCEntry(first_false_negative));
2272 ASSERT(!third_false_negative.HasSameSTCEntry(second_positive));
2273 ASSERT(!third_false_negative.HasSameSTCEntry(second_false_negative));
2276 state.TypeToTest(third_false_negative));
2277 ASSERT(
state.TypeToTest(first_positive) ==
state.TypeToTest(third_positive));
2281 state.InvokeExistingStub(first_positive);
2282 state.InvokeExistingStub(second_positive);
2291 state.InvokeExistingStub(third_positive);
2292 state.InvokeExistingStub(second_positive);
2293 state.InvokeExistingStub(first_positive);
2305#if !defined(PRODUCT)
2306static const char* kLoadedScript =
2310 createAInt() => A<int>();
2311 createAString() => A<String>();
2313 (int, int) createRecordIntInt() => (1, 2);
2314 (String, int) createRecordStringInt() => ("foo", 2);
2315 (int, String) createRecordIntString() => (1, "bar");
2318static const char* kReloadedScript =
2321 class A2<T> extends A<T> {}
2323 createAInt() => A<int>();
2324 createAString() => A<String>();
2325 createA2Int() => A2<int>();
2326 createA2String() => A2<String>();
2328 (int, int) createRecordIntInt() => (1, 2);
2329 (String, int) createRecordStringInt() => ("foo", 2);
2330 (int, String) createRecordIntString() => (1, "bar");
2334 auto*
const zone = thread->zone();
2343 const auto& record_int_int =
2344 Instance::CheckedHandle(zone,
Invoke(root_library,
"createRecordIntInt"));
2345 const auto& record_int_string = Instance::CheckedHandle(
2346 zone,
Invoke(root_library,
"createRecordIntString"));
2347 const auto& record_string_int = Instance::CheckedHandle(
2348 zone,
Invoke(root_library,
"createRecordStringInt"));
2350 const auto& tav_null = Object::null_type_arguments();
2351 const auto& tav_int =
2360 auto& type_record_int_int =
2364 TTSTestState
state(thread, type_a_int);
2365 state.InvokeLazilySpecializedStub({aint, tav_null, tav_null});
2366 state.InvokeExistingStub(
Failure({astring, tav_null, tav_null}));
2368 TTSTestState record_state(thread, type_record_int_int);
2369 record_state.InvokeLazilySpecializedStub(
2370 {record_int_int, tav_null, tav_null});
2371 record_state.InvokeExistingStub(
2372 Failure({record_string_int, tav_null, tav_null}));
2373 record_state.InvokeExistingStub(
2374 Failure({record_int_string, tav_null, tav_null}));
2377 EXPECT(type_a_int.type_test_stub() !=
2379 EXPECT(type_record_int_int.type_test_stub() !=
2388 EXPECT(type_a_int.type_test_stub() ==
2390 EXPECT(type_record_int_int.type_test_stub() ==
2394 (
state.current_stc() ==
state.last_stc().ptr() &&
2395 state.last_stc().NumberOfChecks() == 0));
2397 (record_state.current_stc() == record_state.last_stc().ptr() &&
2398 record_state.last_stc().NumberOfChecks() == 0));
2401 state.InvokeExistingStub(
Failure({astring, tav_null, tav_null}));
2402 state.InvokeExistingStub({a2int, tav_null, tav_null});
2403 state.InvokeExistingStub(
Failure({a2string, tav_null, tav_null}));
2405 record_state.InvokeExistingStub(
2407 record_state.InvokeExistingStub(
2408 Failure({record_string_int, tav_null, tav_null}));
2409 record_state.InvokeExistingStub(
2410 Failure({record_int_string, tav_null, tav_null}));
2421 const auto& tav_null = Object::null_type_arguments();
2422 const auto& tav_int =
2424 const auto& tav_string =
2431 const auto& type_a_t =
Type::Handle(class_a.DeclarationType());
2432 TTSTestCase positive1{aint, tav_int, tav_null};
2433 TTSTestCase positive2{astring, tav_string, tav_null};
2434 TTSTestCase negative1 =
Failure({astring, tav_int, tav_null});
2435 TTSTestCase negative2 =
Failure({aint, tav_string, tav_null});
2436 TTSTestCase false_negative =
FalseNegative({aint, tav_num, tav_null});
2437 TTSTestState
state(thread, type_a_t);
2438 state.InvokeLazilySpecializedStub(positive1);
2439 state.InvokeExistingStub(positive2);
2440 state.InvokeExistingStub(negative1);
2441 state.InvokeExistingStub(negative2);
2442 state.InvokeExistingStub(false_negative);
2450 EXPECT(type_a_t.type_test_stub() ==
2454 (
state.current_stc() ==
state.last_stc().ptr() &&
2455 state.last_stc().NumberOfChecks() == 0));
2458 state.InvokeExistingStub(positive2);
2459 state.InvokeExistingStub(negative1);
2460 state.InvokeExistingStub(negative2);
2461 state.InvokeExistingStub(false_negative);
2462 state.InvokeExistingStub({a2int, tav_int, tav_null});
2463 state.InvokeExistingStub({a2string, tav_string, tav_null});
2464 state.InvokeExistingStub(
Failure({a2string, tav_int, tav_null}));
2465 state.InvokeExistingStub(
Failure({a2int, tav_string, tav_null}));
2516 const intptr_t kNumUnrelated = class_table->
NumCids() - 1;
2519 abstract class B<X> {}
2520 class G<Y> implements B<Y> {}
2521 class C implements B<int> {}
2522 class D implements B<int> {}
2524 for (intptr_t i = 0; i < kNumUnrelated; i++) {
2526 class U%)" Pd R"( {}
2531 class I implements B<String> {
2547 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
2552 EXPECT_EQ(kNumUnrelated, class_b.id() - 1);
2553 EXPECT_EQ(class_b.id() + 1, class_g.id());
2554 EXPECT_EQ(class_c.id() + 1, class_d.id());
2555 EXPECT_EQ(class_d.id() + 1, class_u0.id());
2556 EXPECT_EQ(class_u0.id() + kNumUnrelated, class_i.id());
2557 EXPECT_EQ(class_g.id(), class_i.id() - class_c.id());
2559 const auto& tav_null = Object::null_type_arguments();
2567 TTSTestState
state(thread, type_b_int);
2568 state.InvokeEagerlySpecializedStub(
Failure({obj_i, tav_null, tav_null}));
2571struct STCTestResults {
2572 bool became_hash_cache =
false;
2573 bool cache_capped =
false;
2577 intptr_t num_classes) {
2579 buffer.AddString(
"class D<S> {}\n");
2580 buffer.AddString(
"D<int> Function() createClosureD() => () => D<int>();\n");
2581 for (intptr_t i = 0; i < num_classes; i++) {
2582 buffer.Printf(R
"(class C%)" Pd R"(<S> extends D<S> {}
2583 C%)" Pd R"(<int> Function() createClosureC%)" Pd R"(() => () => C%)" Pd
2595 TransitionNativeToVM transition(thread);
2596 Zone*
const zone = thread->zone();
2598 const auto& root_lib =
2600 EXPECT(!root_lib.IsNull());
2603 ASSERT(!class_d.IsNull());
2605 SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
2608 const auto& object_d =
2609 Instance::CheckedHandle(zone,
Invoke(root_lib,
"createClosureD"));
2610 ASSERT(!object_d.IsNull());
2611 auto& type_closure_d_int =
2615 const auto& tav_null = Object::null_type_arguments();
2617 TTSTestState
state(thread, type_closure_d_int);
2619 state.InvokeEagerlySpecializedStub(
2620 {Object::null_object(), tav_null, tav_null, can_be_null ?
kTTS :
kFail});
2624 STCTestResults results;
2625 for (intptr_t i = 0; i < num_classes; ++i) {
2628 ASSERT(!class_c.IsNull());
2630 SafepointWriteRwLocker ml(thread,
2631 thread->isolate_group()->program_lock());
2637 TTSTestCase base_case = {object_c, tav_null, tav_null};
2639 if (i >= FLAG_max_subtype_cache_entries) {
2641 FLAG_max_subtype_cache_entries);
2645 results.cache_capped =
true;
2647 const bool was_hash =
state.last_stc().IsHash();
2653 }
else if (was_hash) {
2656 }
else if (
state.last_stc().IsHash()) {
2657 results.became_hash_cache =
true;
2668 const intptr_t num_classes =
2669 Utils::Minimum(
static_cast<intptr_t
>(FLAG_max_subtype_cache_entries),
2673 EXPECT(!results.became_hash_cache);
2674 EXPECT(!results.cache_capped);
2679 const intptr_t num_classes =
2680 Utils::Minimum(
static_cast<intptr_t
>(FLAG_max_subtype_cache_entries),
2684 EXPECT(results.became_hash_cache);
2685 EXPECT(!results.cache_capped);
2691 const intptr_t num_classes = 1.1 * FLAG_max_subtype_cache_entries;
2695 results.became_hash_cache);
2696 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::kLegacy, 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 New(const Class &clazz, const TypeArguments &arguments, Nullability nullability=Nullability::kLegacy, Heap::Space space=Heap::kOld)
static TypePtr ObjectType()
static TypePtr DynamicType()
static TypePtr DartFunctionType()
static TypePtr StringType()
static T Minimum(T x, T y)
#define THR_Print(format,...)
struct _Dart_Handle * Dart_Handle
#define FAIL(name, result)
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
#define DECLARE_FLAG(type, name)
#define DEFINE_FLAG(type, name, default_value, comment)
Dart_NativeFunction function
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
constexpr RegList kDartAvailableCpuRegs
ClassPtr GetClass(const Library &lib, const char *name)
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)
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
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 ISOLATE_UNIT_TEST_CASE(name)
#define EXPECT_VALID(handle)