public void AddDependency(DependencyNodeCore <NodeFactory> newDependency) { if (_dependenciesNoLongerMutable) { throw new Exception(); } _dependencies.Add(newDependency); }
public void AddCompilationDiscoveredDependency(DependencyNodeCore <NodeFactory> node, string reason) { Debug.Assert(!_dependenciesQueried); if (_compilationDiscoveredDependencies == null) { _compilationDiscoveredDependencies = new List <DependencyListEntry>(); } _compilationDiscoveredDependencies.Add(new DependencyNodeCore <NodeFactory> .DependencyListEntry(node, reason)); }
protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { IMethodBodyNode methodBodyNode = obj as IMethodBodyNode; var methodNode = methodBodyNode as IMethodNode; if (methodNode != null) { _methodsGenerated.Add(methodNode.Method); } }
private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { var eetypeNode = obj as EETypeNode; if (eetypeNode != null) { _typesWithEETypesGenerated.Add(eetypeNode.Type); AddGeneratedType(eetypeNode.Type); return; } IMethodNode methodNode = obj as MethodCodeNode; if (methodNode == null) { methodNode = obj as ShadowConcreteMethodNode <MethodCodeNode>; } if (methodNode != null) { MethodDesc method = methodNode.Method; if (method.IsCanonicalMethod(CanonicalFormKind.Specific)) { // Canonical methods are not interesting. return; } AddGeneratedType(method.OwningType); _methodDefinitionsGenerated.Add(method.GetTypicalMethodDefinition()); _methodsGenerated.Add(method); return; } var nonGcStaticSectionNode = obj as NonGCStaticsNode; if (nonGcStaticSectionNode != null && _nodeFactory.TypeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type)) { _cctorContextsGenerated.Add(nonGcStaticSectionNode); } var gvmEntryNode = obj as TypeGVMEntriesNode; if (gvmEntryNode != null) { _typeGVMEntries.Add(gvmEntryNode); } var dictionaryNode = obj as GenericDictionaryNode; if (dictionaryNode != null) { _genericDictionariesGenerated.Add(dictionaryNode); } }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencyList = new DependencyNodeCore <NodeFactory> .DependencyList(); if (_type is MetadataType && _constructed && _type.RuntimeInterfaces.Length > 0) { dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map"); } dependencyList.Add(factory.EETypeOptionalFields(_optionalFieldsBuilder), "EEType optional fields"); return(dependencyList); }
private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { var eetypeNode = obj as EETypeNode; if (eetypeNode != null) { _typesWithEETypesGenerated.Add(eetypeNode.Type); AddGeneratedType(eetypeNode.Type); return; } IMethodNode methodNode = obj as MethodCodeNode; if (methodNode == null) { methodNode = obj as ShadowConcreteMethodNode <MethodCodeNode>; } if (methodNode == null) { methodNode = obj as NonExternMethodSymbolNode; } if (methodNode != null) { MethodDesc method = methodNode.Method; AddGeneratedMethod(method); return; } var nonGcStaticSectionNode = obj as NonGCStaticsNode; if (nonGcStaticSectionNode != null && _typeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type)) { _cctorContextsGenerated.Add(nonGcStaticSectionNode); } var gvmEntryNode = obj as TypeGVMEntriesNode; if (gvmEntryNode != null) { _typeGVMEntries.Add(gvmEntryNode); } var dictionaryNode = obj as GenericDictionaryNode; if (dictionaryNode != null) { _genericDictionariesGenerated.Add(dictionaryNode); } }
protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { IMethodBodyNode methodBodyNode = obj as IMethodBodyNode; var methodNode = methodBodyNode as IMethodNode; if (methodNode != null) { lock (_methodsGenerated) { Debug.Assert(!_sortedMethods); _methodsGenerated.Add(methodNode.Method); } } }
private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { var eetypeNode = obj as EETypeNode; if (eetypeNode != null) { AddGeneratedType(eetypeNode.Type); return; } var methodNode = obj as MethodCodeNode; if (methodNode != null) { AddGeneratedType(methodNode.Method.OwningType); return; } }
public int Compare(DependencyNodeCore<NodeFactory> x1, DependencyNodeCore<NodeFactory> y1) { ObjectNode x = x1 as ObjectNode; ObjectNode y = y1 as ObjectNode; if (x == y) { return 0; } // Sort non-object nodes after ObjectNodes if (x == null) return 1; if (y == null) return -1; return CompareImpl(x, y, _comparer); }
protected override void GetDependenciesDueToMethodCodePresence(ref DependencyNodeCore <NodeFactory> .DependencyList dependencies, NodeFactory factory, MethodDesc method) { if (_ilProvider != null) { MethodIL methodIL = _ilProvider.GetMethodIL(method); if (methodIL != null) { try { ReflectionMethodBodyScanner.ScanMarshalOnly(ref dependencies, factory, methodIL); } catch (TypeSystemException) { // A problem with the IL - we just don't scan it... } } } }
protected override void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { base.Graph_NewMarkedNode(obj); var moduleMetadataNode = obj as ModuleMetadataNode; if (moduleMetadataNode != null) { _modulesWithMetadata.Add(moduleMetadataNode.Module); } var fieldMetadataNode = obj as FieldMetadataNode; if (fieldMetadataNode != null) { _fieldsWithMetadata.Add(fieldMetadataNode.Field); } var methodMetadataNode = obj as MethodMetadataNode; if (methodMetadataNode != null) { _methodsWithMetadata.Add(methodMetadataNode.Method); } var typeMetadataNode = obj as TypeMetadataNode; if (typeMetadataNode != null) { _typesWithMetadata.Add(typeMetadataNode.Type); } var customAttributeMetadataNode = obj as CustomAttributeMetadataNode; if (customAttributeMetadataNode != null) { _customAttributesWithMetadata.Add(customAttributeMetadataNode.CustomAttribute); } }
void ComputeDependencySizeAndRelocData(ObjectNode.ObjectData objectData, Dictionary <DependencyNodeCore <NodeFactory>, object> relocTargets, List <ObjectNode> nodesToEmit, ref int totalAllocSizeNeeded, ref int nonObjectRelocTargets) { foreach (var reloc in objectData.Relocs) { DependencyNodeCore <NodeFactory> relocTargetAsNode = (DependencyNodeCore <NodeFactory>)reloc.Target; if (!relocTargets.ContainsKey(relocTargetAsNode)) { relocTargets.Add(relocTargetAsNode, null); ObjectNode relocTargetObjectNode = relocTargetAsNode as ObjectNode; if (relocTargetObjectNode != null) { UpdateBytesUsed(relocTargetObjectNode.GetData(_nodeFactory), ref totalAllocSizeNeeded); nodesToEmit.Add(relocTargetObjectNode); } else { nonObjectRelocTargets++; } } } }
public void Add(ReadyToRunSectionType id, DependencyNodeCore <NodeFactory> node, ISymbolNode startSymbol) { _items.Add(new HeaderItem(id, node, startSymbol)); }
public HeaderItem(ReadyToRunSectionType id, DependencyNodeCore <NodeFactory> node, ISymbolNode startSymbol) { Id = id; Node = node; StartSymbol = startSymbol; }
protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { var eetypeNode = obj as EETypeNode; if (eetypeNode != null) { _typesWithEETypesGenerated.Add(eetypeNode.Type); if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode) { _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type); } return; } IMethodBodyNode methodBodyNode = obj as IMethodBodyNode; if (methodBodyNode != null) { _methodBodiesGenerated.Add(methodBodyNode); } IMethodNode methodNode = methodBodyNode; if (methodNode != null) { if (AllMethodsCanBeReflectable) { _reflectableMethods.Add(methodNode.Method); } } if (methodNode == null) { methodNode = obj as ShadowConcreteMethodNode; } if (methodNode != null) { _methodsGenerated.Add(methodNode.Method); return; } var reflectableMethodNode = obj as ReflectableMethodNode; if (reflectableMethodNode != null) { _reflectableMethods.Add(reflectableMethodNode.Method); } var nonGcStaticSectionNode = obj as NonGCStaticsNode; if (nonGcStaticSectionNode != null && nonGcStaticSectionNode.HasCCtorContext) { _cctorContextsGenerated.Add(nonGcStaticSectionNode); } var gvmEntryNode = obj as TypeGVMEntriesNode; if (gvmEntryNode != null) { _typeGVMEntries.Add(gvmEntryNode); } var dictionaryNode = obj as GenericDictionaryNode; if (dictionaryNode != null) { _genericDictionariesGenerated.Add(dictionaryNode); if (dictionaryNode.OwningEntity is MethodDesc method && AllMethodsCanBeReflectable) { _reflectableMethods.Add(method); } } if (obj is StructMarshallingDataNode structMarshallingDataNode) { _typesWithStructMarshalling.Add(structMarshallingDataNode.Type); } if (obj is DelegateMarshallingDataNode delegateMarshallingDataNode) { _typesWithDelegateMarshalling.Add(delegateMarshallingDataNode.Type); } if (obj is NativeLayoutTemplateMethodSignatureVertexNode templateMethodEntry) { _templateMethodEntries.Add(templateMethodEntry); } }
private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { var eetypeNode = obj as EETypeNode; if (eetypeNode != null) { _typesWithEETypesGenerated.Add(eetypeNode.Type); AddGeneratedType(eetypeNode.Type); if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode) { _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type); } return; } IMethodNode methodNode = obj as MethodCodeNode; if (methodNode == null) { methodNode = obj as ShadowConcreteMethodNode; } if (methodNode == null) { methodNode = obj as NonExternMethodSymbolNode; } if (methodNode != null) { MethodDesc method = methodNode.Method; AddGeneratedMethod(method); return; } var runtimeMethodHandleNode = obj as RuntimeMethodHandleNode; if (runtimeMethodHandleNode != null) { AddMetadataOnlyMethod(runtimeMethodHandleNode.Method); return; } var nonGcStaticSectionNode = obj as NonGCStaticsNode; if (nonGcStaticSectionNode != null && _typeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type)) { _cctorContextsGenerated.Add(nonGcStaticSectionNode); } var gvmEntryNode = obj as TypeGVMEntriesNode; if (gvmEntryNode != null) { _typeGVMEntries.Add(gvmEntryNode); } var dictionaryNode = obj as GenericDictionaryNode; if (dictionaryNode != null) { _genericDictionariesGenerated.Add(dictionaryNode); } var virtualMethodUseNode = obj as VirtualMethodUseNode; if (virtualMethodUseNode != null && virtualMethodUseNode.Method.IsAbstract) { AddGeneratedMethod(virtualMethodUseNode.Method); return; } var gvmDependenciesNode = obj as GVMDependenciesNode; if (gvmDependenciesNode != null && gvmDependenciesNode.Method.IsAbstract) { AddGeneratedMethod(gvmDependenciesNode.Method); } }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencyList = new DependencyNodeCore<NodeFactory>.DependencyList(); if (_type is MetadataType && _constructed && _type.RuntimeInterfaces.Length > 0) { dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map"); } dependencyList.Add(factory.EETypeOptionalFields(_optionalFieldsBuilder), "EEType optional fields"); return dependencyList; }
public override IEnumerable <CombinedDependencyListEntry> SearchDynamicDependencies(List <DependencyNodeCore <NodeFactory> > markedNodes, int firstNode, NodeFactory factory) { Debug.Assert(_method.IsVirtual && _method.HasInstantiation); List <CombinedDependencyListEntry> dynamicDependencies = new List <CombinedDependencyListEntry>(); for (int i = firstNode; i < markedNodes.Count; i++) { DependencyNodeCore <NodeFactory> entry = markedNodes[i]; EETypeNode entryAsEETypeNode = entry as EETypeNode; if (entryAsEETypeNode == null) { continue; } TypeDesc potentialOverrideType = entryAsEETypeNode.Type; if (!potentialOverrideType.IsDefType) { continue; } Debug.Assert(!potentialOverrideType.IsRuntimeDeterminedSubtype); if (potentialOverrideType.IsInterface) { if (_method.OwningType.HasSameTypeDefinition(potentialOverrideType) && (potentialOverrideType != _method.OwningType)) { if (potentialOverrideType.CanCastTo(_method.OwningType)) { // Variance expansion MethodDesc matchingMethodOnRelatedVariantMethod = potentialOverrideType.GetMethod(_method.Name, _method.GetTypicalMethodDefinition().Signature); matchingMethodOnRelatedVariantMethod = _method.Context.GetInstantiatedMethod(matchingMethodOnRelatedVariantMethod, _method.Instantiation); dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(matchingMethodOnRelatedVariantMethod), null, "GVM Variant Interface dependency")); } } continue; } // If this is an interface gvm, look for types that implement the interface // and other instantantiations that have the same canonical form. // This ensure the various slot numbers remain equivalent across all types where there is an equivalence // relationship in the vtable. if (_method.OwningType.IsInterface) { foreach (DefType interfaceImpl in potentialOverrideType.RuntimeInterfaces) { if (interfaceImpl == _method.OwningType) { MethodDesc slotDecl = potentialOverrideType.ResolveInterfaceMethodTarget(_method.GetMethodDefinition()); if (slotDecl != null) { MethodDesc implementingMethodInstantiation = _method.Context.GetInstantiatedMethod(slotDecl, _method.Instantiation); dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(implementingMethodInstantiation), null, "ImplementingMethodInstantiation")); } } } } else { // Quickly check if the potential overriding type is at all related to the GVM's owning type (there is no need // to do any processing for a type that is not at all related to the GVM's owning type. Resolving virtuals is expensive). TypeDesc overrideTypeCur = potentialOverrideType; { do { if (overrideTypeCur == _method.OwningType) { break; } overrideTypeCur = overrideTypeCur.BaseType; }while (overrideTypeCur != null); if (overrideTypeCur == null) { continue; } } overrideTypeCur = potentialOverrideType; while (overrideTypeCur != null) { if (overrideTypeCur == _method.OwningType) { // The GVMDependencyNode already declares the entrypoint/dictionary dependencies of the current method // as static dependencies, therefore we can break the loop as soon we hit the current method's owning type // while we're traversing the hierarchy of the potential derived types. break; } MethodDesc instantiatedTargetMethod = overrideTypeCur.FindVirtualFunctionTargetMethodOnObjectType(_method); if (instantiatedTargetMethod != null) { dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(instantiatedTargetMethod), null, "DerivedMethodInstantiation")); } overrideTypeCur = overrideTypeCur.BaseType; } } } return(dynamicDependencies); }
protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { var eetypeNode = obj as EETypeNode; if (eetypeNode != null) { _typesWithEETypesGenerated.Add(eetypeNode.Type); if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode) { _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type); } return; } IMethodBodyNode methodBodyNode = obj as IMethodBodyNode; if (methodBodyNode != null) { _methodBodiesGenerated.Add(methodBodyNode); } IMethodNode methodNode = methodBodyNode; if (methodNode == null) { methodNode = obj as ShadowConcreteMethodNode; } if (methodNode != null) { _methodsGenerated.Add(methodNode.Method); return; } var reflectableMethodNode = obj as ReflectableMethodNode; if (reflectableMethodNode != null) { _methodsGenerated.Add(reflectableMethodNode.Method); } var nonGcStaticSectionNode = obj as NonGCStaticsNode; if (nonGcStaticSectionNode != null && nonGcStaticSectionNode.HasCCtorContext) { _cctorContextsGenerated.Add(nonGcStaticSectionNode); } var gvmEntryNode = obj as TypeGVMEntriesNode; if (gvmEntryNode != null) { _typeGVMEntries.Add(gvmEntryNode); } var dictionaryNode = obj as GenericDictionaryNode; if (dictionaryNode != null) { _genericDictionariesGenerated.Add(dictionaryNode); } if (obj is StructMarshallingDataNode structMarshallingDataNode) { _typesWithStructMarshalling.Add(structMarshallingDataNode.Type); } if (obj is DelegateMarshallingDataNode delegateMarshallingDataNode) { _typesWithDelegateMarshalling.Add(delegateMarshallingDataNode.Type); } if (obj is DynamicInvokeTemplateNode dynamicInvokeTemplate) { _dynamicInvokeTemplates.Add(dynamicInvokeTemplate.Method); } }
public override IEnumerable <CombinedDependencyListEntry> SearchDynamicDependencies(List <DependencyNodeCore <NodeFactory> > markedNodes, int firstNode, NodeFactory factory) { List <CombinedDependencyListEntry> dynamicDependencies = new List <CombinedDependencyListEntry>(); TypeDesc methodOwningType = _method.OwningType; bool methodIsShared = _method.IsSharedByGenericInstantiations; TypeSystemContext context = _method.Context; for (int i = firstNode; i < markedNodes.Count; i++) { DependencyNodeCore <NodeFactory> entry = markedNodes[i]; EETypeNode entryAsEETypeNode = entry as EETypeNode; if (entryAsEETypeNode == null) { continue; } TypeDesc potentialOverrideType = entryAsEETypeNode.Type; if (!potentialOverrideType.IsDefType || potentialOverrideType.IsInterface) { continue; } // If method is canonical, don't allow using it with non-canonical types - we can wait until // we see the __Canon instantiation. If there isn't one, the canonical method wouldn't be useful anyway. if (methodIsShared && potentialOverrideType.ConvertToCanonForm(CanonicalFormKind.Specific) != potentialOverrideType) { continue; } // Similarly, if the type is canonical but this method instantiation isn't, don't mix them. if (!methodIsShared && potentialOverrideType.IsCanonicalSubtype(CanonicalFormKind.Any)) { continue; } // If this is an interface gvm, look for types that implement the interface // and other instantantiations that have the same canonical form. // This ensure the various slot numbers remain equivalent across all types where there is an equivalence // relationship in the vtable. if (methodOwningType.IsInterface) { // We go over definitions because a single canonical interface method could actually be implemented // by multiple methods - consider: // // class Foo<T, U> : IFoo<T>, IFoo<U>, IFoo<string> { } // // If we ask what implements IFoo<__Canon>.Method, the answer could be "three methods" // and that's expected. We therefore resolve IFoo<__Canon>.Method for each IFoo<!0>.Method, // IFoo<!1>.Method, and IFoo<string>.Method, adding GVMDependencies for each. TypeDesc potentialOverrideDefinition = potentialOverrideType.GetTypeDefinition(); DefType[] potentialInterfaces = potentialOverrideType.RuntimeInterfaces; DefType[] potentialDefinitionInterfaces = potentialOverrideDefinition.RuntimeInterfaces; for (int interfaceIndex = 0; interfaceIndex < potentialInterfaces.Length; interfaceIndex++) { if (potentialInterfaces[interfaceIndex].ConvertToCanonForm(CanonicalFormKind.Specific) == methodOwningType) { MethodDesc interfaceMethod = _method.GetMethodDefinition(); if (methodOwningType.HasInstantiation) { interfaceMethod = context.GetMethodForInstantiatedType( _method.GetTypicalMethodDefinition(), (InstantiatedType)potentialDefinitionInterfaces[interfaceIndex]); } MethodDesc slotDecl = potentialOverrideDefinition.InstantiateAsOpen().ResolveInterfaceMethodTarget(interfaceMethod); if (slotDecl == null) { // The method might be implemented through a default interface method var result = potentialOverrideDefinition.InstantiateAsOpen().ResolveInterfaceMethodToDefaultImplementationOnType(interfaceMethod, out slotDecl); if (result != DefaultInterfaceMethodResolution.DefaultImplementation) { slotDecl = null; } } if (slotDecl != null) { TypeDesc[] openInstantiation = new TypeDesc[_method.Instantiation.Length]; for (int instArg = 0; instArg < openInstantiation.Length; instArg++) { openInstantiation[instArg] = context.GetSignatureVariable(instArg, method: true); } MethodDesc implementingMethodInstantiation = slotDecl.MakeInstantiatedMethod(openInstantiation).InstantiateSignature(potentialOverrideType.Instantiation, _method.Instantiation); dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(implementingMethodInstantiation.GetCanonMethodTarget(CanonicalFormKind.Specific)), null, "ImplementingMethodInstantiation")); } } } } else { // This is not an interface GVM. Check whether the current type overrides the virtual method. // We might need to change what virtual method we ask about - consider: // // class Base<T> { virtual Method(); } // class Derived : Base<string> { override Method(); } // // We need to resolve Base<__Canon>.Method on Derived, but if we were to ask the virtual // method resolution algorithm, the answer would be "does not override" because Base<__Canon> // is not even in the inheritance hierarchy. // // So we need to modify the question to resolve Base<string>.Method instead and then // canonicalize the result. TypeDesc overrideTypeCur = potentialOverrideType; do { if (overrideTypeCur.ConvertToCanonForm(CanonicalFormKind.Specific) == methodOwningType) { break; } overrideTypeCur = overrideTypeCur.BaseType; }while (overrideTypeCur != null); if (overrideTypeCur == null) { continue; } MethodDesc methodToResolve; if (methodOwningType == overrideTypeCur) { methodToResolve = _method; } else { methodToResolve = context .GetMethodForInstantiatedType(_method.GetTypicalMethodDefinition(), (InstantiatedType)overrideTypeCur) .MakeInstantiatedMethod(_method.Instantiation); } MethodDesc instantiatedTargetMethod = potentialOverrideType.FindVirtualFunctionTargetMethodOnObjectType(methodToResolve) .GetCanonMethodTarget(CanonicalFormKind.Specific); if (instantiatedTargetMethod != _method) { dynamicDependencies.Add(new CombinedDependencyListEntry( factory.GVMDependencies(instantiatedTargetMethod), null, "DerivedMethodInstantiation")); } } } return(dynamicDependencies); }
private void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { var eetypeNode = obj as EETypeNode; if (eetypeNode != null) { _typesWithEETypesGenerated.Add(eetypeNode.Type); if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode) { _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type); } return; } IMethodNode methodNode = obj as MethodCodeNode; if (methodNode == null) { methodNode = obj as ShadowConcreteMethodNode; } if (methodNode == null) { methodNode = obj as NonExternMethodSymbolNode; } if (methodNode != null) { _methodsGenerated.Add(methodNode.Method); return; } var reflectableMethodNode = obj as ReflectableMethodNode; if (reflectableMethodNode != null) { _methodsGenerated.Add(reflectableMethodNode.Method); } var nonGcStaticSectionNode = obj as NonGCStaticsNode; if (nonGcStaticSectionNode != null && _typeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type)) { _cctorContextsGenerated.Add(nonGcStaticSectionNode); } var gvmEntryNode = obj as TypeGVMEntriesNode; if (gvmEntryNode != null) { _typeGVMEntries.Add(gvmEntryNode); } var dictionaryNode = obj as GenericDictionaryNode; if (dictionaryNode != null) { _genericDictionariesGenerated.Add(dictionaryNode); } // TODO: temporary until we have an IL scanning Metadata Manager. We shouldn't have to keep track of these. var moduleMetadataNode = obj as ModuleMetadataNode; if (moduleMetadataNode != null) { _modulesWithMetadata.Add(moduleMetadataNode.Module); } }
public override IntPtr OnEntryPoint(MethodEntrypointPtr methodEntrypoint, IntPtr callerArgs) { lock (this) { if (_corInfoImpl == null) { InitJitCodeManager(RuntimeAugments.RhGetOSModuleForMrt()); // TODO: Recycle jit interface object and TypeSystemContext _context = TypeSystemContextFactory.Create(); Compilation compilation = new Compilation(_context); _nodeFactory = compilation.NodeFactory; JitConfigProvider configProvider = new JitConfigProvider(new CorJitFlag[] { CorJitFlag.CORJIT_FLAG_DEBUG_CODE }, Array.Empty <KeyValuePair <string, string> >()); _corInfoImpl = new CorInfoImpl(compilation, configProvider); } MethodDesc methodToCompile = methodEntrypoint.MethodIdentifier.ToMethodDesc(_context); JitMethodCodeNode codeNode = new JitMethodCodeNode(methodToCompile); _corInfoImpl.CompileMethod(codeNode); ObjectNode.ObjectData codeData = codeNode.GetData(null, false); List <ObjectNode> nodesToEmit = new List <ObjectNode>(); Dictionary <DependencyNodeCore <NodeFactory>, object> relocTargets = new Dictionary <DependencyNodeCore <NodeFactory>, object>(); int totalAllocSizeNeeded = 0; int nonObjectRelocTargets = 0; nodesToEmit.Add(codeNode); UpdateBytesUsed(codeNode.GetData(_nodeFactory), ref totalAllocSizeNeeded); int offsetOfEHData = totalAllocSizeNeeded; if (codeNode.EHInfo != null) { Debug.Assert(codeNode.EHInfo.Alignment == 1); // Assert needed as otherwise offsetOfEHData will be wrong UpdateBytesUsed(codeNode.EHInfo, ref totalAllocSizeNeeded); ComputeDependencySizeAndRelocData(codeNode.EHInfo, relocTargets, nodesToEmit, ref totalAllocSizeNeeded, ref nonObjectRelocTargets); } for (int i = 0; i < nodesToEmit.Count; i++) { ObjectNode objNode = nodesToEmit[i]; ComputeDependencySizeAndRelocData(objNode.GetData(_nodeFactory, true), relocTargets, nodesToEmit, ref totalAllocSizeNeeded, ref nonObjectRelocTargets); } if (nonObjectRelocTargets != 0) { totalAllocSizeNeeded = totalAllocSizeNeeded.AlignUp(IntPtr.Size); } int relocTargetOffsetStart = totalAllocSizeNeeded; DependencyNodeCore <NodeFactory>[] relocTargetsArray = new DependencyNodeCore <NodeFactory> [nonObjectRelocTargets]; { int iRelocTarget = 0; foreach (var relocTarget in relocTargets) { if (!(relocTarget.Key is ObjectNode)) { relocTargetsArray[iRelocTarget] = relocTarget.Key; totalAllocSizeNeeded += IntPtr.Size; iRelocTarget++; } } Debug.Assert(iRelocTarget == nonObjectRelocTargets); } GenericDictionaryCell[] genDictCells = new GenericDictionaryCell[relocTargetsArray.Length]; for (int iRelocTarget = 0; iRelocTarget < relocTargetsArray.Length; iRelocTarget++) { DependencyNodeCore <NodeFactory> relocTarget = relocTargetsArray[iRelocTarget]; GenericDictionaryCell newCell = null; if (relocTarget is ExternObjectSymbolNode) { var externObjectSymbolNode = (ExternObjectSymbolNode)relocTarget; var newMethodCell = externObjectSymbolNode.GetDictionaryCell(); newCell = newMethodCell; } if (newCell == null) { Environment.FailFast("Unknown reloc target type"); } genDictCells[iRelocTarget] = newCell; } IntPtr[] relocTargetsAsIntPtr = null; TypeLoaderEnvironment.Instance.RunUnderTypeLoaderLock( () => { TypeBuilderApi.ResolveMultipleCells(genDictCells, out relocTargetsAsIntPtr); }); // Layout of allocated memory... // ObjectNodes (aligned as appropriate) IntPtr pCodeManager; IntPtr jittedCode = AllocJittedCode(checked ((uint)totalAllocSizeNeeded), 8 /* TODO, alignment calculation */, out pCodeManager); int currentOffset = 0; foreach (var node in nodesToEmit) { ObjectNode.ObjectData objectData = node.GetData(_nodeFactory); EmitAndRelocData(objectData, jittedCode, relocTargetOffsetStart, ref currentOffset, relocTargetsArray, relocTargetsAsIntPtr); // EHInfo doesn't get its own node, but it does get emitted into the stream. if ((node == codeNode) && (codeNode.EHInfo != null)) { Debug.Assert(offsetOfEHData == currentOffset); EmitAndRelocData(codeNode.EHInfo, jittedCode, relocTargetOffsetStart, ref currentOffset, relocTargetsArray, relocTargetsAsIntPtr); } } foreach (IntPtr ptr in relocTargetsAsIntPtr) { currentOffset = currentOffset.AlignUp(IntPtr.Size); Marshal.WriteIntPtr(jittedCode, currentOffset, ptr); currentOffset += IntPtr.Size; } SetEHInfoPtr(pCodeManager, jittedCode, jittedCode + offsetOfEHData); IntPtr mainRuntimeFunction = IntPtr.Zero; for (int i = 0; i < codeNode.FrameInfos.Length; i++) { FrameInfo frame = codeNode.FrameInfos[i]; byte[] frameData = frame.BlobData; byte[] gcInfoData = Array.Empty <byte>(); byte[] gcInfoDataDeref = frameData; if (i == 0) { // For main function, add the gc info to the data gcInfoDataDeref = gcInfoData = codeNode.GCInfo; } IntPtr publishedFunction = PublishRuntimeFunction(pCodeManager, jittedCode, mainRuntimeFunction, checked ((uint)frame.StartOffset), checked ((uint)frame.EndOffset), frameData, checked ((uint)frameData.Length), gcInfoDataDeref, checked ((uint)gcInfoData.Length)); if (i == 0) { mainRuntimeFunction = publishedFunction; } } if (mainRuntimeFunction != IntPtr.Zero) { UpdateRuntimeFunctionTable(pCodeManager); } methodEntrypoint.MethodCode = jittedCode; return(jittedCode); } }
public override IEnumerable <CombinedDependencyListEntry> SearchDynamicDependencies(List <DependencyNodeCore <NodeFactory> > markedNodes, int firstNode, NodeFactory factory) { Debug.Assert(_method.IsVirtual && _method.HasInstantiation); List <CombinedDependencyListEntry> dynamicDependencies = new List <CombinedDependencyListEntry>(); for (int i = firstNode; i < markedNodes.Count; i++) { DependencyNodeCore <NodeFactory> entry = markedNodes[i]; EETypeNode entryAsEETypeNode = entry as EETypeNode; if (entryAsEETypeNode == null) { continue; } TypeDesc potentialOverrideType = entryAsEETypeNode.Type; if (!(potentialOverrideType is DefType)) { continue; } Debug.Assert(!potentialOverrideType.IsRuntimeDeterminedSubtype); if (_method.OwningType.HasSameTypeDefinition(potentialOverrideType) && potentialOverrideType.IsInterface && (potentialOverrideType != _method.OwningType)) { if (_method.OwningType.CanCastTo(potentialOverrideType)) { // Variance expansion MethodDesc matchingMethodOnRelatedVariantMethod = potentialOverrideType.GetMethod(_method.Name, _method.GetTypicalMethodDefinition().Signature); matchingMethodOnRelatedVariantMethod = _method.Context.GetInstantiatedMethod(matchingMethodOnRelatedVariantMethod, _method.Instantiation); dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(matchingMethodOnRelatedVariantMethod), null, "GVM Variant Interface dependency")); } } // If this is an interface gvm, look for types that implement the interface // and other instantantiations that have the same canonical form. // This ensure the various slot numbers remain equivalent across all types where there is an equivalence // relationship in the vtable. if (_method.OwningType.IsInterface) { if (potentialOverrideType.IsInterface) { continue; } foreach (DefType interfaceImpl in potentialOverrideType.RuntimeInterfaces) { if (interfaceImpl.ConvertToCanonForm(CanonicalFormKind.Specific) == _method.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific)) { // Find if the type implements this method. (Note, do this comparision against the generic definition of the method, not the // specific method instantiation that is "method" MethodDesc genericDefinition = interfaceImpl.GetMethod(_method.Name, _method.GetTypicalMethodDefinition().Signature); MethodDesc slotDecl = potentialOverrideType.ResolveInterfaceMethodTarget(genericDefinition); if (slotDecl != null) { CreateDependencyForMethodSlotAndInstantiation(slotDecl, dynamicDependencies, factory); } } } } else { // TODO: Ensure GVM Canon Target TypeDesc overrideTypeCanonCur = potentialOverrideType; TypeDesc methodCanonContainingType = _method.OwningType; while (overrideTypeCanonCur != null) { if (overrideTypeCanonCur.ConvertToCanonForm(CanonicalFormKind.Specific) == methodCanonContainingType.ConvertToCanonForm(CanonicalFormKind.Specific)) { MethodDesc methodDefInDerivedType = potentialOverrideType.GetMethod(_method.Name, _method.GetTypicalMethodDefinition().Signature); if (methodDefInDerivedType != null) { CreateDependencyForMethodSlotAndInstantiation(methodDefInDerivedType, dynamicDependencies, factory); } MethodDesc slotDecl = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(_method); if (slotDecl != null) { CreateDependencyForMethodSlotAndInstantiation(slotDecl.GetMethodDefinition(), dynamicDependencies, factory); } } overrideTypeCanonCur = overrideTypeCanonCur.BaseType; } } } return(dynamicDependencies); }
protected virtual void Graph_NewMarkedNode(DependencyNodeCore <NodeFactory> obj) { var eetypeNode = obj as EETypeNode; if (eetypeNode != null) { _typesWithEETypesGenerated.Add(eetypeNode.Type); if (eetypeNode is ConstructedEETypeNode || eetypeNode is CanonicalEETypeNode) { _typesWithConstructedEETypesGenerated.Add(eetypeNode.Type); } return; } IMethodBodyNode methodBodyNode = obj as IMethodBodyNode; if (methodBodyNode != null) { _methodBodiesGenerated.Add(methodBodyNode); } IMethodNode methodNode = methodBodyNode; if (methodNode == null) { methodNode = obj as ShadowConcreteMethodNode; } if (methodNode != null) { _methodsGenerated.Add(methodNode.Method); return; } var reflectableMethodNode = obj as ReflectableMethodNode; if (reflectableMethodNode != null) { _methodsGenerated.Add(reflectableMethodNode.Method); } var nonGcStaticSectionNode = obj as NonGCStaticsNode; if (nonGcStaticSectionNode != null && _typeSystemContext.HasLazyStaticConstructor(nonGcStaticSectionNode.Type)) { _cctorContextsGenerated.Add(nonGcStaticSectionNode); } var gvmEntryNode = obj as TypeGVMEntriesNode; if (gvmEntryNode != null) { _typeGVMEntries.Add(gvmEntryNode); } var dictionaryNode = obj as GenericDictionaryNode; if (dictionaryNode != null) { _genericDictionariesGenerated.Add(dictionaryNode); } var ctorFromLazyGenericsNode = obj as DefaultConstructorFromLazyNode; if (ctorFromLazyGenericsNode != null) { _defaultConstructorsNeeded.Add(ctorFromLazyGenericsNode); } }