|
10 | 10 | using Internal.TypeSystem; |
11 | 11 |
|
12 | 12 | using ILCompiler.DependencyAnalysisFramework; |
| 13 | +using Internal.ReadyToRunConstants; |
13 | 14 |
|
14 | 15 | namespace ILCompiler.DependencyAnalysis |
15 | 16 | { |
@@ -126,14 +127,100 @@ private bool TriggersLazyStaticConstructor(NodeFactory factory) |
126 | 127 | return factory.PreinitializationManager.HasLazyStaticConstructor(type.ConvertToCanonForm(CanonicalFormKind.Specific)); |
127 | 128 | } |
128 | 129 |
|
| 130 | + private static bool ContainsCanonicalTypes(Instantiation instantiation) |
| 131 | + { |
| 132 | + foreach (TypeDesc arg in instantiation) |
| 133 | + { |
| 134 | + if (arg.IsCanonicalSubtype(CanonicalFormKind.Any)) |
| 135 | + return true; |
| 136 | + } |
| 137 | + return false; |
| 138 | + } |
| 139 | + |
129 | 140 | public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation) |
130 | 141 | { |
131 | 142 | DependencyList result = new DependencyList(); |
132 | 143 |
|
133 | 144 | var lookupContext = new GenericLookupResultContext(_dictionaryOwner, typeInstantiation, methodInstantiation); |
134 | | - if (!_lookupSignature.LookupResultIsConcreteAfterInstantiation(lookupContext)) |
| 145 | + |
| 146 | + // Check if the instantiation is not fully concrete (contains canonical types like __Canon) |
| 147 | + bool isNotConcreteInstantiation = ContainsCanonicalTypes(typeInstantiation) || ContainsCanonicalTypes(methodInstantiation); |
| 148 | + |
| 149 | + if (isNotConcreteInstantiation) |
135 | 150 | { |
136 | | - return result.ToArray(); |
| 151 | + switch (_id) |
| 152 | + { |
| 153 | + case ReadyToRunHelperId.MethodHandle: |
| 154 | + case ReadyToRunHelperId.MethodDictionary: |
| 155 | + case ReadyToRunHelperId.VirtualDispatchCell: |
| 156 | + case ReadyToRunHelperId.MethodEntry: |
| 157 | + { |
| 158 | + MethodDesc instantiatedMethod = ((MethodDesc)_target).GetNonRuntimeDeterminedMethodFromRuntimeDeterminedMethodViaSubstitution(typeInstantiation, methodInstantiation); |
| 159 | + if (instantiatedMethod.IsCanonicalMethod(CanonicalFormKind.Any)) |
| 160 | + { |
| 161 | + if (!instantiatedMethod.IsAbstract) |
| 162 | + { |
| 163 | + result.Add(new DependencyListEntry( |
| 164 | + factory.ShadowGenericMethod(instantiatedMethod), |
| 165 | + "Partially instantiated generic dictionary dependencies")); |
| 166 | + } |
| 167 | + return result.ToArray(); |
| 168 | + } |
| 169 | + } |
| 170 | + break; |
| 171 | + |
| 172 | + case ReadyToRunHelperId.TypeHandle: |
| 173 | + case ReadyToRunHelperId.NecessaryTypeHandle: |
| 174 | + case ReadyToRunHelperId.MetadataTypeHandle: |
| 175 | + case ReadyToRunHelperId.TypeHandleForCasting: |
| 176 | + case ReadyToRunHelperId.GetGCStaticBase: |
| 177 | + case ReadyToRunHelperId.GetNonGCStaticBase: |
| 178 | + case ReadyToRunHelperId.GetThreadStaticBase: |
| 179 | + case ReadyToRunHelperId.DefaultConstructor: |
| 180 | + case ReadyToRunHelperId.ObjectAllocator: |
| 181 | + { |
| 182 | + TypeDesc instantiatedType = ((TypeDesc)_target).GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(typeInstantiation, methodInstantiation); |
| 183 | + if (instantiatedType.IsCanonicalSubtype(CanonicalFormKind.Any)) |
| 184 | + { |
| 185 | + return result.ToArray(); |
| 186 | + } |
| 187 | + } |
| 188 | + break; |
| 189 | + |
| 190 | + case ReadyToRunHelperId.FieldHandle: |
| 191 | + { |
| 192 | + FieldDesc field = (FieldDesc)_target; |
| 193 | + TypeDesc instantiatedOwningType = field.OwningType.GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(typeInstantiation, methodInstantiation); |
| 194 | + if (instantiatedOwningType.IsCanonicalSubtype(CanonicalFormKind.Any)) |
| 195 | + { |
| 196 | + return result.ToArray(); |
| 197 | + } |
| 198 | + } |
| 199 | + break; |
| 200 | + |
| 201 | + case ReadyToRunHelperId.DelegateCtor: |
| 202 | + { |
| 203 | + DelegateCreationInfo createInfo = (DelegateCreationInfo)_target; |
| 204 | + MethodDesc instantiatedMethod = createInfo.PossiblyUnresolvedTargetMethod.GetNonRuntimeDeterminedMethodFromRuntimeDeterminedMethodViaSubstitution(typeInstantiation, methodInstantiation); |
| 205 | + if (instantiatedMethod.IsCanonicalMethod(CanonicalFormKind.Any)) |
| 206 | + { |
| 207 | + return result.ToArray(); |
| 208 | + } |
| 209 | + } |
| 210 | + break; |
| 211 | + |
| 212 | + case ReadyToRunHelperId.ConstrainedDirectCall: |
| 213 | + { |
| 214 | + ConstrainedCallInfo callInfo = (ConstrainedCallInfo)_target; |
| 215 | + MethodDesc instantiatedMethod = callInfo.Method.GetNonRuntimeDeterminedMethodFromRuntimeDeterminedMethodViaSubstitution(typeInstantiation, methodInstantiation); |
| 216 | + TypeDesc instantiatedConstrainedType = callInfo.ConstrainedType.GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(typeInstantiation, methodInstantiation); |
| 217 | + if (instantiatedMethod.IsCanonicalMethod(CanonicalFormKind.Any) || instantiatedConstrainedType.IsCanonicalSubtype(CanonicalFormKind.Any)) |
| 218 | + { |
| 219 | + return result.ToArray(); |
| 220 | + } |
| 221 | + } |
| 222 | + break; |
| 223 | + } |
137 | 224 | } |
138 | 225 |
|
139 | 226 | switch (_id) |
|
0 commit comments