Example #1
0
        protected override void OnMarked(NodeFactory factory)
        {
            UtcNodeFactory hostedFactory = factory as UtcNodeFactory;

            Debug.Assert(hostedFactory != null);
            hostedFactory.GCStaticDescRegion.AddEmbeddedObject(this);
        }
Example #2
0
        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)));
        }
Example #3
0
        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);
        }
Example #4
0
        private ISymbolNode GCStaticsSymbol(NodeFactory factory)
        {
            UtcNodeFactory utcNodeFactory = (UtcNodeFactory)factory;

            if (_isThreadStatic)
            {
                return(utcNodeFactory.TypeThreadStaticsSymbol(_type));
            }
            else
            {
                return(utcNodeFactory.TypeGCStaticsSymbol(_type));
            }
        }
Example #5
0
        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());
        }
Example #7
0
        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);
                }
            }
        }
Example #8
0
        /// <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
                }
            }
        }
Example #9
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.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 }));
        }