/// <summary> /// Gets the node representing the target method of the delegate if no runtime lookup is needed. /// </summary> public ISymbolNode GetTargetNode(NodeFactory factory) { Debug.Assert(!NeedsRuntimeLookup); switch (_targetKind) { case TargetKind.CanonicalEntrypoint: return(factory.CanonicalEntrypoint(TargetMethod, TargetMethodIsUnboxingThunk)); case TargetKind.ExactCallableAddress: return(factory.ExactCallableAddress(TargetMethod, TargetMethodIsUnboxingThunk)); case TargetKind.InterfaceDispatch: return(factory.InterfaceDispatchCell(TargetMethod)); case TargetKind.MethodHandle: return(factory.RuntimeMethodHandle(TargetMethod)); case TargetKind.VTableLookup: Debug.Fail("Need to do runtime lookup"); return(null); default: Debug.Assert(false); return(null); } }
public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId lookupKind, object targetOfLookup) { switch (lookupKind) { case ReadyToRunHelperId.TypeHandle: return(NodeFactory.ConstructedTypeSymbol((TypeDesc)targetOfLookup)); case ReadyToRunHelperId.NecessaryTypeHandle: return(NodeFactory.NecessaryTypeSymbol((TypeDesc)targetOfLookup)); case ReadyToRunHelperId.TypeHandleForCasting: { var type = (TypeDesc)targetOfLookup; if (type.IsNullable) { targetOfLookup = type.Instantiation[0]; } return(NodeFactory.NecessaryTypeSymbol((TypeDesc)targetOfLookup)); } case ReadyToRunHelperId.MethodDictionary: return(NodeFactory.MethodGenericDictionary((MethodDesc)targetOfLookup)); case ReadyToRunHelperId.MethodEntry: return(NodeFactory.FatFunctionPointer((MethodDesc)targetOfLookup)); case ReadyToRunHelperId.MethodHandle: return(NodeFactory.RuntimeMethodHandle((MethodDesc)targetOfLookup)); case ReadyToRunHelperId.FieldHandle: return(NodeFactory.RuntimeFieldHandle((FieldDesc)targetOfLookup)); case ReadyToRunHelperId.DefaultConstructor: { var type = (TypeDesc)targetOfLookup; MethodDesc ctor = type.GetDefaultConstructor(); if (ctor == null) { MetadataType activatorType = TypeSystemContext.SystemModule.GetKnownType("System", "Activator"); MetadataType classWithMissingCtor = activatorType.GetKnownNestedType("ClassWithMissingConstructor"); ctor = classWithMissingCtor.GetParameterlessConstructor(); } return(NodeFactory.CanonicalEntrypoint(ctor)); } case ReadyToRunHelperId.ObjectAllocator: { var type = (TypeDesc)targetOfLookup; return(NodeFactory.ExternSymbol(JitHelper.GetNewObjectHelperForType(type))); } default: throw new NotImplementedException(); } }
public void AddCompilationRoot(MethodDesc method, string reason, string exportName = null) { IMethodNode methodEntryPoint = _factory.CanonicalEntrypoint(method); _graph.AddRoot(methodEntryPoint, reason); if (exportName != null) { _factory.NodeAliases.Add(methodEntryPoint, exportName); } }
public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId lookupKind, object targetOfLookup) { switch (lookupKind) { case ReadyToRunHelperId.TypeHandle: return(NodeFactory.ConstructedTypeSymbol(WithoutFunctionPointerType((TypeDesc)targetOfLookup))); case ReadyToRunHelperId.NecessaryTypeHandle: return(NecessaryTypeSymbolIfPossible(WithoutFunctionPointerType((TypeDesc)targetOfLookup))); case ReadyToRunHelperId.TypeHandleForCasting: { var type = (TypeDesc)targetOfLookup; if (type.IsNullable) { targetOfLookup = type.Instantiation[0]; } return(NecessaryTypeSymbolIfPossible((TypeDesc)targetOfLookup)); } case ReadyToRunHelperId.MethodDictionary: return(NodeFactory.MethodGenericDictionary((MethodDesc)targetOfLookup)); case ReadyToRunHelperId.MethodEntry: return(NodeFactory.FatFunctionPointer((MethodDesc)targetOfLookup)); case ReadyToRunHelperId.MethodHandle: return(NodeFactory.RuntimeMethodHandle((MethodDesc)targetOfLookup)); case ReadyToRunHelperId.FieldHandle: return(NodeFactory.RuntimeFieldHandle((FieldDesc)targetOfLookup)); case ReadyToRunHelperId.DefaultConstructor: { var type = (TypeDesc)targetOfLookup; MethodDesc ctor = GetConstructorForCreateInstanceIntrinsic(type); return(NodeFactory.CanonicalEntrypoint(ctor)); } case ReadyToRunHelperId.ObjectAllocator: { var type = (TypeDesc)targetOfLookup; return(NodeFactory.ExternSymbol(JitHelper.GetNewObjectHelperForType(type))); } default: throw new NotImplementedException(); } }
protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); // If we don't have precise field usage information, apply policy that all fields that // are eligible to have metadata get metadata. if (!_hasPreciseFieldUsageInformation) { TypeDesc typeDefinition = type.GetTypeDefinition(); foreach (FieldDesc field in typeDefinition.GetFields()) { if ((GetMetadataCategory(field) & MetadataCategory.Description) != 0) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.FieldMetadata(field), "Field of a reflectable type"); } } } // If anonymous type heuristic is turned on and this is an anonymous type, make sure we have // method bodies for all properties. It's common to have anonymous types used with reflection // and it's hard to specify them in RD.XML. if ((_generationOptions & UsageBasedMetadataGenerationOptions.AnonymousTypeHeuristic) != 0) { if (type is MetadataType metadataType && metadataType.HasInstantiation && !metadataType.IsGenericDefinition && metadataType.HasCustomAttribute("System.Runtime.CompilerServices", "CompilerGeneratedAttribute") && metadataType.Name.Contains("AnonymousType")) { foreach (MethodDesc method in type.GetMethods()) { if (!method.Signature.IsStatic && method.IsSpecialName) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Anonymous type accessor"); } } } } }
protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); // If we don't have precise field usage information, apply policy that all fields that // are eligible to have metadata get metadata. if (!_hasPreciseFieldUsageInformation) { TypeDesc typeDefinition = type.GetTypeDefinition(); foreach (FieldDesc field in typeDefinition.GetFields()) { if ((GetMetadataCategory(field) & MetadataCategory.Description) != 0) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.FieldMetadata(field), "Field of a reflectable type"); } } } // If anonymous type heuristic is turned on and this is an anonymous type, make sure we have // method bodies for all properties. It's common to have anonymous types used with reflection // and it's hard to specify them in RD.XML. if ((_generationOptions & UsageBasedMetadataGenerationOptions.AnonymousTypeHeuristic) != 0) { if (type is MetadataType metadataType && metadataType.HasInstantiation && !metadataType.IsGenericDefinition && metadataType.HasCustomAttribute("System.Runtime.CompilerServices", "CompilerGeneratedAttribute") && metadataType.Name.Contains("AnonymousType")) { foreach (MethodDesc method in type.GetMethods()) { if (!method.Signature.IsStatic && method.IsSpecialName) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Anonymous type accessor"); } } } } // If the option was specified to root types and methods in all user assemblies, do that. if ((_generationOptions & UsageBasedMetadataGenerationOptions.FullUserAssemblyRooting) != 0) { if (type is MetadataType metadataType && !_rootAllAssembliesExaminedModules.Contains(metadataType.Module)) { _rootAllAssembliesExaminedModules.Add(metadataType.Module); if (metadataType.Module is Internal.TypeSystem.Ecma.EcmaModule ecmaModule && !FrameworkStringResourceBlockingPolicy.IsFrameworkAssembly(ecmaModule)) { dependencies = dependencies ?? new DependencyList(); var rootProvider = new RootingServiceProvider(factory, dependencies.Add); foreach (TypeDesc t in ecmaModule.GetAllTypes()) { RootingHelpers.TryRootType(rootProvider, t, "RD.XML root"); } } } } // If a type is marked [Serializable], make sure a couple things are also included. if (type.IsSerializable && !type.IsGenericDefinition) { foreach (MethodDesc method in type.GetAllMethods()) { MethodSignature signature = method.Signature; if (method.IsConstructor && signature.Length == 2 && signature[0] == _serializationInfoType /* && signature[1] is StreamingContext */) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Binary serialization"); } // Methods with these attributes can be called during serialization if (signature.Length == 1 && !signature.IsStatic && signature.ReturnType.IsVoid && (method.HasCustomAttribute("System.Runtime.Serialization", "OnSerializingAttribute") || method.HasCustomAttribute("System.Runtime.Serialization", "OnSerializedAttribute") || method.HasCustomAttribute("System.Runtime.Serialization", "OnDeserializingAttribute") || method.HasCustomAttribute("System.Runtime.Serialization", "OnDeserializedAttribute"))) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Binary serialization"); } } } // Event sources need their special nested types if (type is MetadataType mdType && mdType.HasCustomAttribute("System.Diagnostics.Tracing", "EventSourceAttribute")) { AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Keywords")); AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Tasks")); AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Opcodes")); void AddEventSourceSpecialTypeDependencies(ref DependencyList dependencies, NodeFactory factory, MetadataType type) { if (type != null) { const string reason = "Event source"; dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.TypeMetadata(type), reason); foreach (FieldDesc field in type.GetFields()) { if (field.IsLiteral) { dependencies.Add(factory.FieldMetadata(field), reason); } } } } } }
protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); // If we don't have precise field usage information, apply policy that all fields that // are eligible to have metadata get metadata. if (!_hasPreciseFieldUsageInformation) { TypeDesc typeDefinition = type.GetTypeDefinition(); foreach (FieldDesc field in typeDefinition.GetFields()) { if ((GetMetadataCategory(field) & MetadataCategory.Description) != 0) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.FieldMetadata(field), "Field of a reflectable type"); } } } MetadataType mdType = type as MetadataType; // If anonymous type heuristic is turned on and this is an anonymous type, make sure we have // method bodies for all properties. It's common to have anonymous types used with reflection // and it's hard to specify them in RD.XML. if ((_generationOptions & UsageBasedMetadataGenerationOptions.AnonymousTypeHeuristic) != 0) { if (mdType != null && mdType.HasInstantiation && !mdType.IsGenericDefinition && mdType.HasCustomAttribute("System.Runtime.CompilerServices", "CompilerGeneratedAttribute") && mdType.Name.Contains("AnonymousType")) { foreach (MethodDesc method in type.GetMethods()) { if (!method.Signature.IsStatic && method.IsSpecialName) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Anonymous type accessor"); } } } } ModuleDesc module = mdType?.Module; if (module != null && !_rootEntireAssembliesExaminedModules.Contains(module)) { // If the owning assembly needs to be fully compiled, do that. _rootEntireAssembliesExaminedModules.Add(module); string assemblyName = module.Assembly.GetName().Name; bool fullyRoot; string reason; if (_rootEntireAssembliesModules.Contains(assemblyName)) { // If the assembly was specified as a root on the command line, root it fullyRoot = true; reason = "Rooted from command line"; } else if (_trimmedAssemblies.Contains(assemblyName) || IsTrimmableAssembly(module)) { // If the assembly was specified as trimmed on the command line, do not root // If the assembly is marked trimmable via an attribute, do not root fullyRoot = false; reason = null; } else { // If rooting default assemblies was requested, root fullyRoot = (_generationOptions & UsageBasedMetadataGenerationOptions.RootDefaultAssemblies) != 0; reason = "Assemblies rooted from command line"; } if (fullyRoot) { dependencies = dependencies ?? new DependencyList(); var rootProvider = new RootingServiceProvider(factory, dependencies.Add); foreach (TypeDesc t in mdType.Module.GetAllTypes()) { RootingHelpers.TryRootType(rootProvider, t, reason); } } } // Event sources need their special nested types if (mdType != null && mdType.HasCustomAttribute("System.Diagnostics.Tracing", "EventSourceAttribute")) { AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Keywords")); AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Tasks")); AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Opcodes")); void AddEventSourceSpecialTypeDependencies(ref DependencyList dependencies, NodeFactory factory, MetadataType type) { if (type != null) { const string reason = "Event source"; dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.TypeMetadata(type), reason); foreach (FieldDesc field in type.GetFields()) { if (field.IsLiteral) { dependencies.Add(factory.FieldMetadata(field), reason); } } } } } }
protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); // If we don't have precise field usage information, apply policy that all fields that // are eligible to have metadata get metadata. if (!_hasPreciseFieldUsageInformation) { TypeDesc typeDefinition = type.GetTypeDefinition(); foreach (FieldDesc field in typeDefinition.GetFields()) { if ((GetMetadataCategory(field) & MetadataCategory.Description) != 0) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.FieldMetadata(field), "Field of a reflectable type"); } } } // If anonymous type heuristic is turned on and this is an anonymous type, make sure we have // method bodies for all properties. It's common to have anonymous types used with reflection // and it's hard to specify them in RD.XML. if ((_generationOptions & UsageBasedMetadataGenerationOptions.AnonymousTypeHeuristic) != 0) { if (type is MetadataType metadataType && metadataType.HasInstantiation && !metadataType.IsGenericDefinition && metadataType.HasCustomAttribute("System.Runtime.CompilerServices", "CompilerGeneratedAttribute") && metadataType.Name.Contains("AnonymousType")) { foreach (MethodDesc method in type.GetMethods()) { if (!method.Signature.IsStatic && method.IsSpecialName) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Anonymous type accessor"); } } } } // If a type is marked [Serializable], make sure a couple things are also included. if (type.IsSerializable && !type.IsGenericDefinition) { foreach (MethodDesc method in type.GetAllMethods()) { MethodSignature signature = method.Signature; if (method.IsConstructor && signature.Length == 2 && signature[0] == _serializationInfoType /* && signature[1] is StreamingContext */) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Binary serialization"); } // Methods with these attributes can be called during serialization if (signature.Length == 1 && !signature.IsStatic && signature.ReturnType.IsVoid && (method.HasCustomAttribute("System.Runtime.Serialization", "OnSerializingAttribute") || method.HasCustomAttribute("System.Runtime.Serialization", "OnSerializedAttribute") || method.HasCustomAttribute("System.Runtime.Serialization", "OnDeserializingAttribute") || method.HasCustomAttribute("System.Runtime.Serialization", "OnDeserializedAttribute"))) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Binary serialization"); } } } }