[vm,aot] Restore generation of TTS for type arguments passed to factory constructors

This is a follow-up to https://dart-review.googlesource.com/c/sdk/+/501762.

TEST=ci
Fixes https://github.com/dart-lang/sdk/issues/63404

Change-Id: I85386738c203a7fb27171bf904723106b764288e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/504680
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
Alexander Markov
2026-05-20 15:11:47 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 4b609fd598
commit c93a1c2bc3
3 changed files with 41 additions and 8 deletions
+17
View File
@@ -5950,6 +5950,23 @@ void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler->GenerateStaticCall(deopt_id(), source(), function(), args_info,
locs(), *call_ic_data, rebind_rule_,
entry_kind());
if (function().IsFactory()) {
TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
if (type_usage_info != nullptr) {
const Class& klass = Class::Handle(function().Owner());
if (klass.NumTypeArguments() > 0) {
if (type_args_len() > 0) {
RegisterTypeArgumentsUse(compiler->function(), type_usage_info, klass,
ArgumentAt(0),
/*convert_to_instance_type_arguments=*/true);
} else {
type_usage_info->UseTypeArgumentsInInstanceCreation(
klass, TypeArguments::Handle(
zone, klass.GetDeclarationInstanceTypeArguments()));
}
}
}
}
}
CachableIdempotentCallInstr::CachableIdempotentCallInstr(
+22 -7
View File
@@ -1262,7 +1262,8 @@ void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
void RegisterTypeArgumentsUse(const Function& function,
TypeUsageInfo* type_usage_info,
const Class& klass,
Definition* type_arguments) {
Definition* type_arguments,
bool convert_to_instance_type_arguments) {
// The [type_arguments] can, in the general case, be any kind of [Definition]
// but generally (in order of expected frequency)
//
@@ -1286,15 +1287,28 @@ void RegisterTypeArgumentsUse(const Function& function,
if (ConstantInstr* constant = type_arguments->AsConstant()) {
const Object& object = constant->value();
ASSERT(object.IsNull() || object.IsTypeArguments());
const TypeArguments& type_arguments =
TypeArguments::Handle(TypeArguments::RawCast(object.ptr()));
type_usage_info->UseTypeArgumentsInInstanceCreation(klass, type_arguments);
auto& ta = TypeArguments::Handle(TypeArguments::RawCast(object.ptr()));
if (convert_to_instance_type_arguments) {
if (!ta.IsNull() && (ta.Length() > klass.NumTypeParameters())) {
// Account for sharing of larger type arguments vectors.
ta = ta.TruncatedTo(klass.NumTypeParameters());
}
ta = klass.GetInstanceTypeArguments(Thread::Current(), ta);
}
type_usage_info->UseTypeArgumentsInInstanceCreation(klass, ta);
} else if (InstantiateTypeArgumentsInstr* instantiate =
type_arguments->AsInstantiateTypeArguments()) {
if (instantiate->type_arguments()->BindsToConstant() &&
!instantiate->type_arguments()->BoundConstant().IsNull()) {
const auto& ta =
TypeArguments::Cast(instantiate->type_arguments()->BoundConstant());
auto& ta = TypeArguments::Handle(TypeArguments::RawCast(
instantiate->type_arguments()->BoundConstant().ptr()));
if (convert_to_instance_type_arguments) {
if (!ta.IsNull() && (ta.Length() > klass.NumTypeParameters())) {
// Account for sharing of larger type arguments vectors.
ta = ta.TruncatedTo(klass.NumTypeParameters());
}
ta = klass.GetInstanceTypeArguments(Thread::Current(), ta);
}
type_usage_info->UseTypeArgumentsInInstanceCreation(klass, ta);
}
} else if (LoadFieldInstr* load_field = type_arguments->AsLoadField()) {
@@ -1362,7 +1376,8 @@ void RegisterTypeArgumentsUse(const Function& function,
void RegisterTypeArgumentsUse(const Function& function,
TypeUsageInfo* type_usage_info,
const Class& klass,
Definition* type_arguments) {
Definition* type_arguments,
bool convert_to_instance_type_arguments) {
// We only have a [TypeUsageInfo] object available durin AOT compilation.
UNREACHABLE();
}
+2 -1
View File
@@ -264,7 +264,8 @@ class TypeUsageInfo : public ThreadStackResource {
void RegisterTypeArgumentsUse(const Function& function,
TypeUsageInfo* type_usage_info,
const Class& klass,
Definition* type_arguments);
Definition* type_arguments,
bool convert_to_instance_type_arguments = false);
#endif
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)