Example #1
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            NativeWriter    nativeWriter  = new NativeWriter();
            VertexHashtable hashtable     = new VertexHashtable();
            Section         nativeSection = nativeWriter.NewSection();

            nativeSection.Place(hashtable);

            foreach (var type in factory.MetadataManager.GetTypesWithEETypes())
            {
                // If this is an instantiated non-canonical generic type, add it to the generic instantiations hashtable
                if (!type.HasInstantiation || type.IsGenericDefinition || type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    continue;
                }

                var    typeSymbol      = factory.NecessaryTypeSymbol(type);
                uint   instantiationId = _externalReferences.GetIndex(typeSymbol);
                Vertex hashtableEntry  = nativeWriter.GetUnsignedConstant(instantiationId);

                hashtable.Append((uint)type.GetHashCode(), nativeSection.Place(hashtableEntry));
            }

            byte[] streamBytes = nativeWriter.Save();

            _endSymbol.SetSymbolOffset(streamBytes.Length);

            return(new ObjectData(streamBytes, Array.Empty <Relocation>(), 1, new ISymbolNode[] { this, _endSymbol }));
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            // Zero out the dictionary so that we AV if someone tries to insert after we're done.
            _insertedSymbolsDictionary = null;

            var builder = new ObjectDataBuilder(factory);

            foreach (ISymbolNode symbol in _insertedSymbols)
            {
                // TODO: set low bit if the linkage of the symbol is IAT_PVALUE.
                builder.EmitPointerReloc(symbol);
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);

            builder.DefinedSymbols.Add(this);
            builder.DefinedSymbols.Add(_endSymbol);

            return(builder.ToObjectData());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // The dependency tracking of this node currently does nothing because the data emission relies
            // the set of compiled methods which has an incomplete state during dependency tracking.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);
            objData.AddSymbol(_endSymbol);

            RelocType reloc = factory.Target.Abi == TargetAbi.CoreRT ?
                              RelocType.IMAGE_REL_BASED_RELPTR32 : RelocType.IMAGE_REL_BASED_ADDR32NB;

            foreach (var mappingEntry in factory.MetadataManager.GetStackTraceMapping(factory))
            {
                objData.EmitReloc(factory.MethodEntrypoint(mappingEntry.Entity), reloc);
                objData.EmitInt(mappingEntry.MetadataHandle);
            }

            _endSymbol.SetSymbolOffset(objData.CountBytes);
            return(objData.ToObjectData());
        }
Example #4
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            foreach (var delegateEntry in factory.MetadataManager.DelegateMarshalingThunks)
            {
                Internal.TypeSystem.TypeDesc delegateType = delegateEntry.Value.DelegateType;
                Vertex vertex = writer.GetTuple(
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(delegateType))),
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.MethodEntrypoint(delegateEntry.Value)))
                    );

                int hashCode = delegateType.GetHashCode();
                typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolNode[] { this, _endSymbol }));
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            builder.Alignment = factory.Target.PointerSize;

            if (_sorter != null)
            {
                _nestedNodesList.Sort(_sorter);
            }

            builder.DefinedSymbols.Add(_startSymbol);
            foreach (EmbeddedObjectNode node in _nestedNodesList)
            {
                if (!relocsOnly)
                {
                    node.Offset = builder.CountBytes;
                }

                node.EncodeData(ref builder, factory, relocsOnly);
                if (node is ISymbolNode)
                {
                    builder.DefinedSymbols.Add((ISymbolNode)node);
                }
            }
            _endSymbol.SetSymbolOffset(builder.CountBytes);
            builder.DefinedSymbols.Add(_endSymbol);

            ObjectData objData = builder.ToObjectData();

            return(objData);
        }
Example #6
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            foreach (var mappingEntry in factory.MetadataManager.GetTypeDefinitionMapping())
            {
                var node = (EETypeNode)factory.ConstructedTypeSymbol(mappingEntry.Entity);
                if (node.Marked)
                {
                    // TODO: this format got very inefficient due to not being able to use RVAs
                    //       replace with a hash table

                    builder.EmitPointerReloc(node);
                    builder.EmitInt(mappingEntry.MetadataHandle);

                    if (factory.Target.PointerSize == 8)
                    {
                        builder.EmitInt(0); // Pad
                    }
                }
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);

            builder.DefinedSymbols.Add(this);
            builder.DefinedSymbols.Add(_endSymbol);

            return(builder.ToObjectData());
        }
Example #7
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            NativeWriter    writer    = new NativeWriter();
            VertexHashtable hashtable = new VertexHashtable();
            Section         section   = writer.NewSection();

            section.Place(hashtable);

            foreach (var type in factory.MetadataManager.GetTypesWithConstructedEETypes())
            {
                if (!type.HasInstantiation || type.IsCanonicalSubtype(CanonicalFormKind.Any) || type.IsGenericDefinition)
                {
                    continue;
                }

                MetadataType metadataType = type as MetadataType;
                if (metadataType == null)
                {
                    continue;
                }

                VertexBag bag = new VertexBag();

                if (metadataType.GCStaticFieldSize.AsInt > 0)
                {
                    ISymbolNode gcStaticIndirection = factory.Indirection(factory.TypeGCStaticsSymbol(metadataType));
                    bag.AppendUnsigned(BagElementKind.GcStaticData, _nativeStaticsReferences.GetIndex(gcStaticIndirection));
                }
                if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
                {
                    ISymbolNode nonGCStaticIndirection = factory.Indirection(factory.TypeNonGCStaticsSymbol(metadataType));
                    bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(nonGCStaticIndirection));
                }
                if (metadataType.ThreadGcStaticFieldSize.AsInt > 0)
                {
                    ISymbolNode threadStaticsIndirection = factory.Indirection(factory.TypeThreadStaticIndex(metadataType));
                    bag.AppendUnsigned(BagElementKind.ThreadStaticIndex, _nativeStaticsReferences.GetIndex(threadStaticsIndirection));
                }

                if (bag.ElementsCount > 0)
                {
                    uint   typeId      = _externalReferences.GetIndex(factory.NecessaryTypeSymbol(type));
                    Vertex staticsInfo = writer.GetTuple(writer.GetUnsignedConstant(typeId), bag);

                    hashtable.Append((uint)type.GetHashCode(), section.Place(staticsInfo));
                }
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
Example #8
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // Dependencies for this node are tracked by the method code nodes
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            // Ensure the native layout data has been saved, in order to get valid Vertex offsets for the signature Vertices
            factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory);

            NativeWriter    nativeWriter  = new NativeWriter();
            VertexHashtable hashtable     = new VertexHashtable();
            Section         nativeSection = nativeWriter.NewSection();

            nativeSection.Place(hashtable);

            foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes())
            {
                if (!IsEligibleToHaveATemplate(type))
                {
                    continue;
                }

                if (factory.Target.Abi == TargetAbi.ProjectN)
                {
                    // If the type does not have fully constructed type, don't emit it.
                    // TODO: Remove the workaround once we stop using the STS dependency analysis.
                    if (!factory.ConstructedTypeSymbol(type).Marked)
                    {
                        continue;
                    }
                }

                // Type's native layout info
                NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type);

                // If this template isn't considered necessary, don't emit it.
                if (!templateNode.Marked)
                {
                    continue;
                }
                Vertex nativeLayout = templateNode.SavedVertex;

                // Hashtable Entry
                Vertex entry = nativeWriter.GetTuple(
                    nativeWriter.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(type))),
                    nativeWriter.GetUnsignedConstant((uint)nativeLayout.VertexOffset));

                // Add to the hash table, hashed by the containing type's hashcode
                uint hashCode = (uint)type.GetHashCode();
                hashtable.Append(hashCode, nativeSection.Place(entry));
            }

            byte[] streamBytes = nativeWriter.Save();

            _endSymbol.SetSymbolOffset(streamBytes.Length);

            return(new ObjectData(streamBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
        /// <summary>
        /// Builds a native hashtable containing data about each manifest resource
        /// </summary>
        /// <returns></returns>
        private byte[] GenerateIndexBlob(NodeFactory factory)
        {
            NativeWriter    nativeWriter          = new NativeWriter();
            Section         indexHashtableSection = nativeWriter.NewSection();
            VertexHashtable indexHashtable        = new VertexHashtable();

            indexHashtableSection.Place(indexHashtable);

            // Build a table with a tuple of Assembly Full Name, Resource Name, Offset within the resource data blob, Length
            // for each resource.
            // This generates a hashtable for the convenience of managed code since there's
            // a reader for VertexHashtable, but not for VertexSequence.

            foreach (ResourceIndexData indexData in _resourceDataNode.GetOrCreateIndexData(factory))
            {
                Vertex asmName      = nativeWriter.GetStringConstant(indexData.AssemblyName);
                Vertex resourceName = nativeWriter.GetStringConstant(indexData.ResourceName);
                Vertex offsetVertex = nativeWriter.GetUnsignedConstant((uint)indexData.NativeOffset);
                Vertex lengthVertex = nativeWriter.GetUnsignedConstant((uint)indexData.Length);

                Vertex indexVertex = nativeWriter.GetTuple(asmName, resourceName);
                indexVertex = nativeWriter.GetTuple(indexVertex, offsetVertex);
                indexVertex = nativeWriter.GetTuple(indexVertex, lengthVertex);

                int hashCode = TypeHashingAlgorithms.ComputeNameHashCode(indexData.AssemblyName);
                indexHashtable.Append((uint)hashCode, indexHashtableSection.Place(indexVertex));
            }

            byte[] blob = nativeWriter.Save();
            _endSymbol.SetSymbolOffset(blob.Length);
            return(blob);
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            Debug.Assert(_dynamicInvokeMethodContainerType != null);

            // Ensure the native layout blob has been saved
            factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory);

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);

            if (factory.Target.SupportsRelativePointers)
            {
                objData.EmitReloc(factory.NecessaryTypeSymbol(_dynamicInvokeMethodContainerType), RelocType.IMAGE_REL_BASED_RELPTR32);
            }
            else
            {
                objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_dynamicInvokeMethodContainerType));
            }

            List <KeyValuePair <MethodDesc, int> > sortedList = new List <KeyValuePair <MethodDesc, int> >(_methodToTemplateIndex);

            sortedList.Sort((firstEntry, secondEntry) => firstEntry.Value.CompareTo(secondEntry.Value));

            for (int i = 0; i < sortedList.Count; i++)
            {
                var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(sortedList[i].Key));

                if (factory.Target.SupportsRelativePointers)
                {
                    objData.EmitInt(nameAndSig.SavedVertex.VertexOffset);
                    objData.EmitReloc(factory.MethodEntrypoint(sortedList[i].Key), RelocType.IMAGE_REL_BASED_RELPTR32);
                }
                else
                {
                    objData.EmitNaturalInt(nameAndSig.SavedVertex.VertexOffset);
                    objData.EmitPointerReloc(factory.MethodEntrypoint(sortedList[i].Key));
                }
            }

            _endSymbol.SetSymbolOffset(objData.CountBytes);
            objData.AddSymbol(_endSymbol);

            // Prevent further adds now we're done writing
#if DEBUG
            if (!relocsOnly)
            {
                _dataEmitted = true;
            }
#endif

            return(objData.ToObjectData());
        }
Example #11
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            foreach (var mappingEntry in factory.MetadataManager.GetTypeDefinitionMapping())
            {
                if (!factory.CompilationModuleGroup.ContainsType(mappingEntry.Entity))
                {
                    continue;
                }

                // We are looking for any EEType - constructed or not, it has to be in the mapping
                // table so that we can map it to metadata.
                EETypeNode node = null;

                if (!mappingEntry.Entity.IsGenericDefinition)
                {
                    node = factory.ConstructedTypeSymbol(mappingEntry.Entity) as EETypeNode;
                }

                if (node == null || !node.Marked)
                {
                    // This might have been a typeof() expression.
                    node = factory.NecessaryTypeSymbol(mappingEntry.Entity) as EETypeNode;
                }

                if (node.Marked)
                {
                    Vertex vertex = writer.GetTuple(
                        writer.GetUnsignedConstant(_externalReferences.GetIndex(node)),
                        writer.GetUnsignedConstant((uint)mappingEntry.MetadataHandle)
                        );

                    int hashCode = node.Type.GetHashCode();
                    typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
                }
            }

            MemoryStream ms = new MemoryStream();

            writer.Save(ms);
            byte[] hashTableBytes = ms.ToArray();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolNode[] { this, _endSymbol }));
        }
Example #12
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            var writer = new NativeWriter();
            var reflectionBlockTypeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(reflectionBlockTypeMapHashTable);

            foreach (var type in factory.MetadataManager.GetTypesWithEETypes())
            {
                if (!type.IsTypeDefinition)
                {
                    continue;
                }

                var mdType = type as MetadataType;
                if (mdType == null)
                {
                    continue;
                }

                if (!factory.MetadataManager.IsReflectionBlocked(mdType))
                {
                    continue;
                }

                if (!factory.CompilationModuleGroup.ContainsType(mdType))
                {
                    continue;
                }

                // Go with a necessary type symbol. It will be upgraded to a constructed one if a constructed was emitted.
                IEETypeNode typeSymbol = factory.NecessaryTypeSymbol(type);

                Vertex vertex = writer.GetUnsignedConstant(_externalReferences.GetIndex(typeSymbol));

                int hashCode = typeSymbol.Type.GetHashCode();
                reflectionBlockTypeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            MemoryStream ms = new MemoryStream();

            writer.Save(ms);
            byte[] hashTableBytes = ms.ToArray();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolNode[] { this, _endSymbol }));
        }
Example #13
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // Dependencies for this node are tracked by the method code nodes
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            // Ensure the native layout data has been saved, in order to get valid Vertex offsets for the signature Vertices
            factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory);

            NativeWriter    nativeWriter  = new NativeWriter();
            VertexHashtable hashtable     = new VertexHashtable();
            Section         nativeSection = nativeWriter.NewSection();

            nativeSection.Place(hashtable);


            foreach (MethodDesc method in factory.MetadataManager.GetCompiledMethods())
            {
                if (!IsEligibleToBeATemplate(method))
                {
                    continue;
                }

                var methodEntryNode = factory.NativeLayout.TemplateMethodEntry(method);

                if (!methodEntryNode.Marked)
                {
                    continue;
                }

                // Method entry
                Vertex methodEntry = methodEntryNode.SavedVertex;

                // Method's native layout info
                Vertex nativeLayout = factory.NativeLayout.TemplateMethodLayout(method).SavedVertex;

                // Hashtable Entry
                Vertex entry = nativeWriter.GetTuple(
                    nativeWriter.GetUnsignedConstant((uint)methodEntry.VertexOffset),
                    nativeWriter.GetUnsignedConstant((uint)nativeLayout.VertexOffset));

                // Add to the hash table, hashed by the containing type's hashcode
                uint hashCode = (uint)method.GetHashCode();
                hashtable.Append(hashCode, nativeSection.Place(entry));
            }

            byte[] streamBytes = nativeWriter.Save();

            _endSymbol.SetSymbolOffset(streamBytes.Length);

            return(new ObjectData(streamBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
Example #14
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            foreach (var mappingEntry in factory.MetadataManager.GetTypeDefinitionMapping())
            {
                if (!factory.CompilationModuleGroup.ContainsType(mappingEntry.Entity))
                {
                    continue;
                }

                // We are looking for any EEType - constructed or not, it has to be in the mapping
                // table so that we can map it to metadata.
                EETypeNode node = null;

                if (!mappingEntry.Entity.IsGenericDefinition)
                {
                    node = factory.ConstructedTypeSymbol(mappingEntry.Entity) as EETypeNode;
                }

                if (node == null || !node.Marked)
                {
                    // This might have been a typeof() expression.
                    node = factory.NecessaryTypeSymbol(mappingEntry.Entity) as EETypeNode;
                }

                if (node.Marked)
                {
                    // TODO: this format got very inefficient due to not being able to use RVAs
                    //       replace with a hash table

                    builder.EmitPointerReloc(node);
                    builder.EmitInt(mappingEntry.MetadataHandle);

                    if (factory.Target.PointerSize == 8)
                    {
                        builder.EmitInt(0); // Pad
                    }
                }
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);

            builder.DefinedSymbols.Add(this);
            builder.DefinedSymbols.Add(_endSymbol);

            return(builder.ToObjectData());
        }
Example #15
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            foreach (var node in factory.MetadataManager.GetCctorContextMapping())
            {
                MetadataType type = node.Type;

                Debug.Assert(factory.TypeSystemContext.HasLazyStaticConstructor(type));

                // If this type doesn't generate an EEType in the current compilation, don't report it in the table.
                // If nobody can get to the EEType, they can't ask to run the cctor. We don't need to force generate it.
                if (!factory.MetadataManager.TypeGeneratesEEType(type))
                {
                    continue;
                }

                // Hash table is hashed by the hashcode of the owning type.
                // Each entry has: the EEType of the type, followed by the non-GC static base.
                // The non-GC static base is prefixed by the class constructor context.

                // Unfortunately we need to adjust for the cctor context just so that we can subtract it again at runtime...
                int delta = NonGCStaticsNode.GetClassConstructorContextStorageSize(factory.TypeSystemContext.Target, type);

                Vertex vertex = writer.GetTuple(
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(type))),
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(node, delta))
                    );

                int hashCode = type.GetHashCode();
                typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            MemoryStream ms = new MemoryStream();

            writer.Save(ms);
            byte[] hashTableBytes = ms.ToArray();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolNode[] { this, _endSymbol }));
        }
Example #16
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            var writer = new NativeWriter();
            var defaultConstructorHashtable = new VertexHashtable();

            Section defaultConstructorHashtableSection = writer.NewSection();

            defaultConstructorHashtableSection.Place(defaultConstructorHashtable);

            foreach (var type in factory.MetadataManager.GetTypesWithConstructedEETypes())
            {
                MethodDesc defaultCtor = type.GetDefaultConstructor();
                if (defaultCtor == null)
                {
                    continue;
                }

                // We only place default constructors of reflection-blocked types in this table.
                // At runtime, the type loader will search both this table and the invoke map
                // for default constructor info. If the ctor is reflectable, we would have
                // expected dataflow analysis to ensure there's a reflectable method for it.
                // If we don't find a reflectable method for the ctor of a non-blocked type
                // there would have to be a dataflow analysis warning.
                if (!factory.MetadataManager.IsReflectionBlocked(defaultCtor))
                {
                    continue;
                }

                defaultCtor = defaultCtor.GetCanonMethodTarget(CanonicalFormKind.Specific);

                ISymbolNode typeNode        = factory.NecessaryTypeSymbol(type);
                ISymbolNode defaultCtorNode = factory.MethodEntrypoint(defaultCtor, false);

                Vertex vertex = writer.GetTuple(
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(typeNode)),
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(defaultCtorNode)));

                int hashCode = type.GetHashCode();
                defaultConstructorHashtable.Append((uint)hashCode, defaultConstructorHashtableSection.Place(vertex));
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
Example #17
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            foreach (var mappingEntry in factory.MetadataManager.GetTypeDefinitionMapping())
            {
                if (!factory.CompilationModuleGroup.ContainsType(mappingEntry.Entity))
                {
                    continue;
                }

                // Types that don't have EETypes don't need mapping table entries because there's no risk of them
                // not unifying to the same System.Type at runtime.
                if (!factory.MetadataManager.TypeGeneratesEEType(mappingEntry.Entity))
                {
                    continue;
                }

                // Go with a necessary type symbol. It will be upgraded to a constructed one if a constructed was emitted.
                IEETypeNode typeSymbol = factory.NecessaryTypeSymbol(mappingEntry.Entity);

                Vertex vertex = writer.GetTuple(
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(typeSymbol)),
                    writer.GetUnsignedConstant((uint)mappingEntry.MetadataHandle)
                    );

                int hashCode = typeSymbol.Type.GetHashCode();
                typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            MemoryStream ms = new MemoryStream();

            writer.Save(ms);
            byte[] hashTableBytes = ms.ToArray();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolNode[] { this, _endSymbol }));
        }
Example #18
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // Dependencies of the NativeLayoutInfo node are tracked by the callers that emit data into the native layout writer
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            SaveNativeLayoutInfoWriter(factory);

            _endSymbol.SetSymbolOffset(_writerSavedBytes.Length);

            return(new ObjectData(_writerSavedBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
Example #19
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            foreach (var type in factory.MetadataManager.GetTypesWithConstructedEETypes())
            {
                if (!type.IsSzArray)
                {
                    continue;
                }

                var arrayType = (ArrayType)type;

                // This optimization is not compatible with canInlineTypeCheck on JIT/EE interface returning
                // CORINFO_INLINE_TYPECHECK_PASS unconditionally.
                //
                // If we're generating a template for this type, we can skip generating the hashtable entry
                // since the type loader can just create this type at runtime if something needs it. It's
                // okay to have multiple EETypes for the same array type.
                // var canonArrayType = arrayType.ConvertToCanonForm(CanonicalFormKind.Specific);
                // if (arrayType != canonArrayType && factory.NativeLayout.TemplateTypeLayout(canonArrayType).Marked)
                //     continue;

                // Look at the constructed type symbol. If a constructed type wasn't emitted, then the array map entry isn't valid for use
                IEETypeNode arrayTypeSymbol = factory.ConstructedTypeSymbol(arrayType);

                Vertex vertex = writer.GetUnsignedConstant(_externalReferences.GetIndex(arrayTypeSymbol));

                int hashCode = arrayType.GetHashCode();
                typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
Example #20
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            foreach (var arrayType in factory.MetadataManager.GetArrayTypeMapping())
            {
                if (!arrayType.IsSzArray)
                {
                    continue;
                }

                if (!factory.MetadataManager.TypeGeneratesEEType(arrayType))
                {
                    continue;
                }

                if (!arrayType.ElementType.IsValueType)
                {
                    continue;
                }

                // Go with a necessary type symbol. It will be upgraded to a constructed one if a constructed was emitted.
                IEETypeNode arrayTypeSymbol = factory.NecessaryTypeSymbol(arrayType);

                Vertex vertex = writer.GetUnsignedConstant(_externalReferences.GetIndex(arrayTypeSymbol));

                int hashCode = arrayType.GetHashCode();
                typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
Example #21
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            foreach (var node in factory.MetadataManager.GetCctorContextMapping())
            {
                MetadataType type = node.Type;

                Debug.Assert(factory.PreinitializationManager.HasLazyStaticConstructor(type));

                // If this type doesn't generate an MethodTable in the current compilation, don't report it in the table.
                // If nobody can get to the MethodTable, they can't ask to run the cctor. We don't need to force generate it.
                if (!factory.MetadataManager.TypeGeneratesEEType(type))
                {
                    continue;
                }

                // Hash table is hashed by the hashcode of the owning type.
                // Each entry has: the MethodTable of the type, followed by the non-GC static base.
                // The non-GC static base is prefixed by the class constructor context.
                Vertex vertex = writer.GetTuple(
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(type))),
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(node))
                    );

                int hashCode = type.GetHashCode();
                typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
Example #22
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            foreach (var type in factory.MetadataManager.GetTypesWithConstructedEETypes())
            {
                if (!type.IsSzArray)
                {
                    continue;
                }

                var arrayType = (ArrayType)type;

                if (!arrayType.ElementType.IsValueType)
                {
                    continue;
                }

                // Look at the constructed type symbol. If a constructed type wasn't emitted, then the array map entry isn't valid for use
                IEETypeNode arrayTypeSymbol = factory.ConstructedTypeSymbol(arrayType);

                Vertex vertex = writer.GetUnsignedConstant(_externalReferences.GetIndex(arrayTypeSymbol));

                int hashCode = arrayType.GetHashCode();
                typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            var writer = new NativeWriter();
            var defaultConstructorHashtable = new VertexHashtable();

            Section defaultConstructorHashtableSection = writer.NewSection();

            defaultConstructorHashtableSection.Place(defaultConstructorHashtable);

            foreach (var type in factory.MetadataManager.GetTypesWithConstructedEETypes())
            {
                MethodDesc defaultCtor = type.GetDefaultConstructor();
                if (defaultCtor == null)
                {
                    continue;
                }

                defaultCtor = defaultCtor.GetCanonMethodTarget(CanonicalFormKind.Specific);

                ISymbolNode typeNode        = factory.NecessaryTypeSymbol(type);
                ISymbolNode defaultCtorNode = factory.MethodEntrypoint(defaultCtor, false);

                Vertex vertex = writer.GetTuple(
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(typeNode)),
                    writer.GetUnsignedConstant(_externalReferences.GetIndex(defaultCtorNode)));

                int hashCode = type.GetHashCode();
                defaultConstructorHashtable.Append((uint)hashCode, defaultConstructorHashtableSection.Place(vertex));
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            NativeWriter    nativeWriter  = new NativeWriter();
            VertexHashtable hashtable     = new VertexHashtable();
            Section         nativeSection = nativeWriter.NewSection();

            nativeSection.Place(hashtable);

            // We go over constructed EETypes only. The places that need to consult this hashtable at runtime
            // all need constructed EETypes. Placing unconstructed EETypes into this hashtable could make us
            // accidentally satisfy e.g. MakeGenericType for something that was only used in a cast. Those
            // should throw MissingRuntimeArtifact instead.
            //
            // We already make sure "necessary" EETypes that could potentially be loaded at runtime through
            // the dynamic type loader get upgraded to constructed EETypes at AOT compile time.
            foreach (var type in factory.MetadataManager.GetTypesWithConstructedEETypes())
            {
                // If this is an instantiated non-canonical generic type, add it to the generic instantiations hashtable
                if (!type.HasInstantiation || type.IsGenericDefinition || type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    continue;
                }

                var    typeSymbol      = factory.NecessaryTypeSymbol(type);
                uint   instantiationId = _externalReferences.GetIndex(typeSymbol);
                Vertex hashtableEntry  = nativeWriter.GetUnsignedConstant(instantiationId);

                hashtable.Append((uint)type.GetHashCode(), nativeSection.Place(hashtableEntry));
            }

            byte[] streamBytes = nativeWriter.Save();

            _endSymbol.SetSymbolOffset(streamBytes.Length);

            return(new ObjectData(streamBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node has no relocations.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            byte[] blob = ((PrecomputedMetadataManager)factory.MetadataManager).GetStackTraceBlob(factory);
            _endSymbol.SetSymbolOffset(blob.Length);

            return(new ObjectData(
                       blob,
                       Array.Empty <Relocation>(),
                       1,
                       new ISymbolDefinitionNode[]
            {
                this,
                EndSymbol
            }));
        }
Example #26
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node has no relocations.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolNode[] { this }));
            }

            byte[] blob = factory.MetadataManager.GetMetadataBlob();
            _endSymbol.SetSymbolOffset(blob.Length);

            return(new ObjectData(
                       blob,
                       Array.Empty <Relocation>(),
                       1,
                       new ISymbolNode[]
            {
                this,
                _endSymbol
            }));
        }
Example #27
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();

            if (_sorter != null)
            {
                _nestedNodesList.Sort(_sorter);
            }

            builder.AddSymbol(_startSymbol);

            GetElementDataForNodes(ref builder, factory, relocsOnly);

            _endSymbol.SetSymbolOffset(builder.CountBytes);
            builder.AddSymbol(_endSymbol);

            ObjectData objData = builder.ToObjectData();

            return(objData);
        }
Example #28
0
        /// <summary>
        /// Extracts resources from all modules being compiled into a single blob and saves
        /// the information needed to create an index into that blob.
        /// </summary>
        private byte[] GenerateResourceBlob(NodeFactory factory)
        {
            GetOrCreateIndexData(factory);

            // Read resources into the blob
            byte[] resourceBlob = new byte[_totalLength];
            int    currentPos   = 0;

            foreach (ResourceIndexData indexData in _indexData)
            {
                EcmaModule    module            = indexData.EcmaModule;
                PEMemoryBlock resourceDirectory = module.PEReader.GetSectionData(module.PEReader.PEHeaders.CorHeader.ResourcesDirectory.RelativeVirtualAddress);
                Debug.Assert(currentPos == indexData.NativeOffset);
                BlobReader reader       = resourceDirectory.GetReader(indexData.EcmaOffset, indexData.Length);
                byte[]     resourceData = reader.ReadBytes(indexData.Length);
                Buffer.BlockCopy(resourceData, 0, resourceBlob, currentPos, resourceData.Length);
                currentPos += resourceData.Length;
            }

            _endSymbol.SetSymbolOffset(resourceBlob.Length);
            return(resourceBlob);
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            // Ensure the native layout blob has been saved
            factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory);

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);

            if (_methodToTemplateIndex == null)
            {
                BuildMethodToIdMap(factory);
            }

            TypeDesc containerType = null;

            foreach (var method in _methodToTemplateIndex.Keys)
            {
                Debug.Assert(containerType == null || containerType == method.OwningType);
                containerType = method.OwningType;
#if !DEBUG
                break;
#endif
            }

            if (factory.Target.SupportsRelativePointers)
            {
                objData.EmitReloc(factory.NecessaryTypeSymbol(containerType), RelocType.IMAGE_REL_BASED_RELPTR32);
            }
            else
            {
                objData.EmitPointerReloc(factory.NecessaryTypeSymbol(containerType));
            }

            List <KeyValuePair <MethodDesc, int> > sortedList = new List <KeyValuePair <MethodDesc, int> >(_methodToTemplateIndex);
            sortedList.Sort((firstEntry, secondEntry) => firstEntry.Value.CompareTo(secondEntry.Value));

            for (int i = 0; i < sortedList.Count; i++)
            {
                var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(sortedList[i].Key));

                if (factory.Target.SupportsRelativePointers)
                {
                    objData.EmitInt(nameAndSig.SavedVertex.VertexOffset);
                    objData.EmitReloc(factory.MethodEntrypoint(sortedList[i].Key), RelocType.IMAGE_REL_BASED_RELPTR32);
                }
                else
                {
                    objData.EmitNaturalInt(nameAndSig.SavedVertex.VertexOffset);
                    objData.EmitPointerReloc(factory.MethodEntrypoint(sortedList[i].Key));
                }
            }

            _endSymbol.SetSymbolOffset(objData.CountBytes);
            objData.AddSymbol(_endSymbol);

            return(objData.ToObjectData());
        }
Example #30
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            // Ensure the native layout blob has been saved
            factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory);

            var writer           = new NativeWriter();
            var typeMapHashTable = new VertexHashtable();

            Section hashTableSection = writer.NewSection();

            hashTableSection.Place(typeMapHashTable);

            // Get a list of all methods that have a method body and metadata from the metadata manager.
            foreach (var mappingEntry in factory.MetadataManager.GetMethodMapping(factory))
            {
                MethodDesc method = mappingEntry.Entity;

                // The current format requires us to have an EEType for the owning type. We might want to lift this.
                if (!factory.MetadataManager.TypeGeneratesEEType(method.OwningType))
                {
                    continue;
                }

                // We have a method body, we have a metadata token, but we can't get an invoke stub. Bail.
                if (!factory.MetadataManager.IsReflectionInvokable(method))
                {
                    continue;
                }

                InvokeTableFlags flags = 0;

                if (method.HasInstantiation)
                {
                    flags |= InvokeTableFlags.IsGenericMethod;
                }

                if (method.GetCanonMethodTarget(CanonicalFormKind.Specific).RequiresInstArg())
                {
                    flags |= InvokeTableFlags.RequiresInstArg;
                }

                if (method.IsDefaultConstructor)
                {
                    flags |= InvokeTableFlags.IsDefaultConstructor;
                }

                if (ReflectionVirtualInvokeMapNode.NeedsVirtualInvokeInfo(method))
                {
                    flags |= InvokeTableFlags.HasVirtualInvoke;
                }

                if (!method.IsAbstract)
                {
                    flags |= InvokeTableFlags.HasEntrypoint;
                }

                if (mappingEntry.MetadataHandle != 0)
                {
                    flags |= InvokeTableFlags.HasMetadataHandle;
                }

                if (!factory.MetadataManager.HasReflectionInvokeStubForInvokableMethod(method))
                {
                    flags |= InvokeTableFlags.NeedsParameterInterpretation;
                }

                if (method.IsCanonicalMethod(CanonicalFormKind.Universal))
                {
                    flags |= InvokeTableFlags.IsUniversalCanonicalEntry;
                }

                // TODO: native signature for P/Invokes and NativeCallable methods
                if (method.IsRawPInvoke() || method.IsNativeCallable)
                {
                    continue;
                }

                // Grammar of an entry in the hash table:
                // Flags + DeclaringType + MetadataHandle/NameAndSig + Entrypoint + DynamicInvokeMethod + [NumGenericArgs + GenericArgs]

                Vertex vertex = writer.GetUnsignedConstant((uint)flags);

                if ((flags & InvokeTableFlags.HasMetadataHandle) != 0)
                {
                    // Only store the offset portion of the metadata handle to get better integer compression
                    vertex = writer.GetTuple(vertex,
                                             writer.GetUnsignedConstant((uint)(mappingEntry.MetadataHandle & MetadataManager.MetadataOffsetMask)));
                }
                else
                {
                    var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method.GetTypicalMethodDefinition()));
                    vertex = writer.GetTuple(vertex, writer.GetUnsignedConstant((uint)nameAndSig.SavedVertex.VertexOffset));
                }

                // Go with a necessary type symbol. It will be upgraded to a constructed one if a constructed was emitted.
                IEETypeNode owningTypeSymbol = factory.NecessaryTypeSymbol(method.OwningType);
                vertex = writer.GetTuple(vertex,
                                         writer.GetUnsignedConstant(_externalReferences.GetIndex(owningTypeSymbol)));

                if ((flags & InvokeTableFlags.HasEntrypoint) != 0)
                {
                    bool useUnboxingStub = method.OwningType.IsValueType && !method.Signature.IsStatic;
                    vertex = writer.GetTuple(vertex,
                                             writer.GetUnsignedConstant(_externalReferences.GetIndex(
                                                                            factory.MethodEntrypoint(method.GetCanonMethodTarget(CanonicalFormKind.Specific), useUnboxingStub))));
                }

                if ((flags & InvokeTableFlags.NeedsParameterInterpretation) == 0)
                {
                    MethodDesc canonInvokeStubMethod = factory.MetadataManager.GetCanonicalReflectionInvokeStub(method);
                    if (canonInvokeStubMethod.IsSharedByGenericInstantiations)
                    {
                        vertex = writer.GetTuple(vertex,
                                                 writer.GetUnsignedConstant(((uint)factory.MetadataManager.DynamicInvokeTemplateData.GetIdForMethod(canonInvokeStubMethod) << 1) | 1));
                    }
                    else
                    {
                        vertex = writer.GetTuple(vertex,
                                                 writer.GetUnsignedConstant(_externalReferences.GetIndex(factory.MethodEntrypoint(canonInvokeStubMethod)) << 1));
                    }
                }

                if ((flags & InvokeTableFlags.IsGenericMethod) != 0)
                {
                    if ((flags & InvokeTableFlags.IsUniversalCanonicalEntry) != 0)
                    {
                        var nameAndSigGenericMethod = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method));
                        vertex = writer.GetTuple(vertex, writer.GetUnsignedConstant((uint)nameAndSigGenericMethod.SavedVertex.VertexOffset));
                    }
                    else if ((flags & InvokeTableFlags.RequiresInstArg) == 0 || (flags & InvokeTableFlags.HasEntrypoint) == 0)
                    {
                        VertexSequence args = new VertexSequence();
                        for (int i = 0; i < method.Instantiation.Length; i++)
                        {
                            uint argId = _externalReferences.GetIndex(factory.NecessaryTypeSymbol(method.Instantiation[i]));
                            args.Append(writer.GetUnsignedConstant(argId));
                        }
                        vertex = writer.GetTuple(vertex, args);
                    }
                    else
                    {
                        uint dictionaryId = _externalReferences.GetIndex(factory.MethodGenericDictionary(method));
                        vertex = writer.GetTuple(vertex, writer.GetUnsignedConstant(dictionaryId));
                    }
                }

                int hashCode = method.GetCanonMethodTarget(CanonicalFormKind.Specific).OwningType.GetHashCode();
                typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
            }

            byte[] hashTableBytes = writer.Save();

            _endSymbol.SetSymbolOffset(hashTableBytes.Length);

            return(new ObjectData(hashTableBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }));
        }