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()); }
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); }
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()); }
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 })); }
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()); }
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 })); }
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 })); }
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 })); }
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()); }
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 })); }
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 })); }
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 })); }
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 })); }
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 })); }
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 })); }
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 })); }
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 })); }
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 })); }
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); }
/// <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()); }
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 })); }