protected override void OnMarked(NodeFactory factory) { UtcNodeFactory hostedFactory = factory as UtcNodeFactory; Debug.Assert(hostedFactory != null); hostedFactory.GCStaticDescRegion.AddEmbeddedObject(this); }
public override ISymbolNode GetTarget(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation, GenericDictionaryNode dictionary) { UtcNodeFactory utcNodeFactory = factory as UtcNodeFactory; Debug.Assert(utcNodeFactory != null); TypeDesc instantiatedType = _type.InstantiateSignature(typeInstantiation, methodInstantiation); return(factory.Indirection(utcNodeFactory.TypeThreadStaticsIndexSymbol(instantiatedType))); }
public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory) { UtcNodeFactory hostedFactory = factory as UtcNodeFactory; Debug.Assert(hostedFactory != null); DependencyListEntry[] result = new DependencyListEntry[2]; result[0] = new DependencyListEntry(hostedFactory.GCStaticDescRegion, "GCStaticDesc Region"); result[1] = new DependencyListEntry(hostedFactory.TypeGCStaticsSymbol(_type), "GC Static Base Symbol"); return(result); }
private ISymbolNode GCStaticsSymbol(NodeFactory factory) { UtcNodeFactory utcNodeFactory = (UtcNodeFactory)factory; if (_isThreadStatic) { return(utcNodeFactory.TypeThreadStaticsSymbol(_type)); } else { return(utcNodeFactory.TypeGCStaticsSymbol(_type)); } }
public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory) { UtcNodeFactory hostedFactory = factory as UtcNodeFactory; Debug.Assert(hostedFactory != null); bool refersToGCStaticsSymbol = !_type.IsCanonicalSubtype(CanonicalFormKind.Any); DependencyListEntry[] result = new DependencyListEntry[refersToGCStaticsSymbol ? 2 : 1]; result[0] = new DependencyListEntry(hostedFactory.GCStaticDescRegion, "GCStaticDesc Region"); if (refersToGCStaticsSymbol) { result[1] = new DependencyListEntry(hostedFactory.TypeGCStaticsSymbol(_type), "GC Static Base Symbol"); } return(result); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // TODO: define _tls_used as comdat select any when multiple object files present. UtcNodeFactory hostedFactory = factory as UtcNodeFactory; ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly); objData.RequireInitialPointerAlignment(); objData.AddSymbol(this); // Allocate and initialize the IMAGE_TLS_DIRECTORY PE data structure used by the OS loader to determine // TLS allocations. The structure is defined by the OS as following: /* * struct _IMAGE_TLS_DIRECTORY32 * { * DWORD StartAddressOfRawData; * DWORD EndAddressOfRawData; * DWORD AddressOfIndex; * DWORD AddressOfCallBacks; * DWORD SizeOfZeroFill; * DWORD Characteristics; * } * * struct _IMAGE_TLS_DIRECTORY64 * { * ULONGLONG StartAddressOfRawData; * ULONGLONG EndAddressOfRawData; * ULONGLONG AddressOfIndex; * ULONGLONG AddressOfCallBacks; * DWORD SizeOfZeroFill; * DWORD Characteristics; * } */ // In order to utilize linker support, the struct variable needs to be named _tls_used objData.EmitPointerReloc(hostedFactory.TlsStart); // start of tls data objData.EmitPointerReloc(hostedFactory.TlsEnd); // end of tls data objData.EmitPointerReloc(hostedFactory.ThreadStaticsIndex); // address of tls_index objData.EmitZeroPointer(); // pointer to call back array objData.EmitInt(0); // size of tls zero fill objData.EmitInt(0); // characteristics return(objData.ToObjectData()); }
private GCStaticDescRegionNode Region(NodeFactory factory) { UtcNodeFactory utcNodeFactory = (UtcNodeFactory)factory; if (_type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(null); } else { if (_isThreadStatic) { return(utcNodeFactory.ThreadStaticGCDescRegion); } else { return(utcNodeFactory.GCStaticDescRegion); } } }
/// <summary> /// Helper method to compute the dependencies that would be needed by a hashtable entry for statics info lookup. /// This helper is used by EETypeNode, which is used by the dependency analysis to compute the statics hashtable /// entries for the compiled types. /// </summary> public static void AddStaticsInfoDependencies(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { if (!factory.MetadataManager.SupportsReflection) { return; } if (type is MetadataType && type.HasInstantiation && !type.IsCanonicalSubtype(CanonicalFormKind.Any)) { MetadataType metadataType = (MetadataType)type; // NOTE: The StaticsInfoHashtable entries need to reference the gc and non-gc static nodes through an indirection cell. // The StaticsInfoHashtable entries only exist for static fields on generic types. if (metadataType.GCStaticFieldSize.AsInt > 0) { dependencies.Add(factory.Indirection(factory.TypeGCStaticsSymbol(metadataType)), "GC statics indirection for StaticsInfoHashtable"); } if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.TypeSystemContext.HasLazyStaticConstructor(type)) { // The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor // context offset. dependencies.Add(factory.Indirection(factory.TypeNonGCStaticsSymbol(metadataType)), "Non-GC statics indirection for StaticsInfoHashtable"); } if (metadataType.ThreadStaticFieldSize.AsInt > 0) { if (factory.Target.Abi == TargetAbi.ProjectN) { UtcNodeFactory utcFactory = (UtcNodeFactory)factory; dependencies.Add(utcFactory.TypeThreadStaticsIndexSymbol(metadataType), "Thread statics index indirection for StaticsInfoHashtable"); dependencies.Add(utcFactory.TypeThreadStaticsOffsetSymbol(metadataType), "Thread statics offset indirection for StaticsInfoHashtable"); } // TODO: TLS for CoreRT } } }
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.TypeSystemContext.HasLazyStaticConstructor(type)) { ISymbolNode nonGCStaticIndirection = factory.Indirection(factory.TypeNonGCStaticsSymbol(metadataType)); bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(nonGCStaticIndirection)); } if (metadataType.ThreadStaticFieldSize.AsInt > 0) { if (factory.Target.Abi == TargetAbi.ProjectN) { UtcNodeFactory utcFactory = (UtcNodeFactory)factory; ISymbolNode threadStaticIndexIndirection = utcFactory.TypeThreadStaticsIndexSymbol(metadataType); bag.AppendUnsigned(BagElementKind.ThreadStaticIndex, _nativeStaticsReferences.GetIndex(threadStaticIndexIndirection)); ISymbolNode threadStaticOffsetIndirection = utcFactory.TypeThreadStaticsOffsetSymbol(metadataType); bag.AppendUnsigned(BagElementKind.ThreadStaticOffset, _nativeStaticsReferences.GetIndex(threadStaticOffsetIndirection)); } // TODO: TLS for CoreRT } 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 })); }