Beispiel #1
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            // If the type has a class constructor, its non-GC statics section is prefixed
            // by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
            {
                int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment, GetClassConstructorContextAlignment(_type.Context.Target));
                int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
                builder.RequireAlignment(alignmentRequired);

                Debug.Assert(classConstructorContextStorageSize >= GetClassConstructorContextSize(_type.Context.Target));

                // Add padding before the context if alignment forces us to do so
                builder.EmitZeros(classConstructorContextStorageSize - GetClassConstructorContextSize(_type.Context.Target));

                // Emit the actual StaticClassConstructionContext
                var cctorMethod = _type.GetStaticConstructor();
                builder.EmitPointerReloc(factory.MethodEntrypoint(cctorMethod));
                builder.EmitZeroPointer();
            }
            else
            {
                builder.RequireAlignment(_type.NonGCStaticFieldAlignment);
            }

            builder.EmitZeros(_type.NonGCStaticFieldSize);
            builder.DefinedSymbols.Add(this);

            return(builder.ToObjectData());
        }
Beispiel #2
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();

            if (factory.Target.Abi == TargetAbi.CoreRT)
            {
                int delta = GCStaticRegionConstants.Uninitialized;

                // Set the flag that indicates next pointer following EEType is the preinit data
                if (_preInitFieldInfos != null)
                {
                    delta |= GCStaticRegionConstants.HasPreInitializedData;
                }

                builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), delta);

                if (_preInitFieldInfos != null)
                {
                    builder.EmitPointerReloc(factory.GCStaticsPreInitDataNode(_type));
                }
            }
            else
            {
                builder.RequireInitialAlignment(_type.GCStaticFieldAlignment.AsInt);

                // @TODO - emit the frozen array node reloc
                builder.EmitZeros(_type.GCStaticFieldSize.AsInt);
            }

            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
 public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
 {
     ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);
     builder.RequireInitialPointerAlignment();
     builder.EmitZeros(_type.ThreadStaticFieldSize.AsInt);
     builder.AddSymbol(this);
     return builder.ToObjectData();
 }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            MetadataType type = _preinitializationInfo.Type;

            builder.RequireInitialAlignment(factory.Target.PointerSize);

            // GC static fields don't begin at offset 0, need to subtract that.
            int initialOffset = CompilerMetadataFieldLayoutAlgorithm.GetGCStaticFieldOffset(factory.TypeSystemContext).AsInt;

            foreach (FieldDesc field in type.GetFields())
            {
                if (!field.IsStatic || field.HasRva || field.IsLiteral || field.IsThreadStatic || !field.HasGCStaticBase)
                {
                    continue;
                }

                int padding = field.Offset.AsInt - initialOffset - builder.CountBytes;
                Debug.Assert(padding >= 0);
                builder.EmitZeros(padding);

                TypePreinit.ISerializableValue val = _preinitializationInfo.GetFieldValue(field);
                int currentOffset = builder.CountBytes;
                if (val != null)
                {
                    val.WriteFieldData(ref builder, field, factory);
                }
                else
                {
                    builder.EmitZeroPointer();
                }
                Debug.Assert(builder.CountBytes - currentOffset == field.FieldType.GetElementSize().AsInt);
            }

            int pad = _preinitializationInfo.Type.GCStaticFieldSize.AsInt - builder.CountBytes - initialOffset;

            Debug.Assert(pad >= 0);
            builder.EmitZeros(pad);

            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
Beispiel #5
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            // If the type has a class constructor, its non-GC statics section is prefixed
            // by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
            {
                int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
                int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
                builder.RequireInitialAlignment(alignmentRequired);

                Debug.Assert(classConstructorContextStorageSize >= GetClassConstructorContextSize(_type.Context.Target));

                // Add padding before the context if alignment forces us to do so
                builder.EmitZeros(classConstructorContextStorageSize - GetClassConstructorContextSize(_type.Context.Target));

                // Emit the actual StaticClassConstructionContext
                MethodDesc cctorMethod      = _type.GetStaticConstructor();
                MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                if (cctorMethod != canonCctorMethod)
                {
                    builder.EmitPointerReloc(factory.FatFunctionPointer(cctorMethod), FatFunctionPointerConstants.Offset);
                }
                else
                {
                    builder.EmitPointerReloc(factory.MethodEntrypoint(cctorMethod));
                }
                builder.EmitZeroPointer();
            }
            else
            {
                builder.RequireInitialAlignment(_type.NonGCStaticFieldAlignment.AsInt);
            }

            builder.EmitZeros(_type.NonGCStaticFieldSize.AsInt);
            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
Beispiel #6
0
        public static ObjectData GetDataForPreInitDataField(
            ISymbolDefinitionNode node,
            MetadataType _type, List <PreInitFieldInfo> sortedPreInitFields,
            int startOffset,
            NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialAlignment(_type.GCStaticFieldAlignment.AsInt);

            int staticOffset    = startOffset;
            int staticOffsetEnd = _type.GCStaticFieldSize.AsInt;
            int idx             = 0;

            while (staticOffset < staticOffsetEnd)
            {
                PreInitFieldInfo fieldInfo = idx < sortedPreInitFields.Count ? sortedPreInitFields[idx] : null;
                int writeTo = staticOffsetEnd;
                if (fieldInfo != null)
                {
                    writeTo = fieldInfo.Field.Offset.AsInt;
                }

                // Emit the zero before the next preinitField
                builder.EmitZeros(writeTo - staticOffset);
                staticOffset = writeTo;

                if (fieldInfo != null)
                {
                    int count = builder.CountBytes;

                    if (fieldInfo.Field.FieldType.IsValueType)
                    {
                        // Emit inlined data for value types
                        fieldInfo.WriteData(ref builder, factory);
                    }
                    else
                    {
                        // Emit a pointer reloc to the frozen data for reference types
                        builder.EmitPointerReloc(factory.SerializedFrozenArray(fieldInfo));
                    }

                    staticOffset += builder.CountBytes - count;
                    idx++;
                }
            }

            builder.AddSymbol(node);

            return(builder.ToObjectData());
        }
Beispiel #7
0
 public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
 {
     if (factory.Target.Abi == TargetAbi.CoreRT)
     {
         // At runtime, an instance of the GCStaticEEType will be created and a GCHandle to it
         // will be written in this location.
         builder.RequireInitialPointerAlignment();
         builder.EmitPointerReloc(GetGCStaticEETypeNode(factory));
     }
     else
     {
         builder.RequireInitialAlignment(_type.ThreadStaticFieldAlignment.AsInt);
         builder.EmitZeros(_type.ThreadStaticFieldSize.AsInt);
     }
 }
Beispiel #8
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (factory.Target.Abi == TargetAbi.CoreRT || factory.Target.Abi == TargetAbi.CppCodegen)
            {
                ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

                builder.RequireInitialPointerAlignment();

                int delta = GCStaticRegionConstants.Uninitialized;

                // Set the flag that indicates next pointer following EEType is the preinit data
                if (_preInitFieldInfos != null)
                {
                    delta |= GCStaticRegionConstants.HasPreInitializedData;
                }

                builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), delta);

                if (_preInitFieldInfos != null)
                {
                    builder.EmitPointerReloc(factory.GCStaticsPreInitDataNode(_type));
                }

                builder.AddSymbol(this);

                return(builder.ToObjectData());
            }
            else
            {
                if (_preInitFieldInfos == null)
                {
                    ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

                    builder.RequireInitialPointerAlignment();

                    builder.EmitZeros(_type.GCStaticFieldSize.AsInt);

                    builder.AddSymbol(this);

                    return(builder.ToObjectData());
                }
                else
                {
                    _preInitFieldInfos.Sort(PreInitFieldInfo.FieldDescCompare);
                    return(GCStaticsPreInitDataNode.GetDataForPreInitDataField(this, _type, _preInitFieldInfos, 0, factory, relocsOnly));
                }
            }
        }
Beispiel #9
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            builder.RequireInitialPointerAlignment();

            if (factory.Target.Abi == TargetAbi.CoreRT)
            {
                builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), 1);
            }
            else
            {
                builder.RequireInitialAlignment(_type.GCStaticFieldAlignment);
                builder.EmitZeros(_type.GCStaticFieldSize);
            }

            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
        public static ObjectData GetDataForPreInitDataField(
            ISymbolDefinitionNode node,
            MetadataType _type, List <PreInitFieldInfo> sortedPreInitFields,
            int startOffset,
            NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialAlignment(_type.GCStaticFieldAlignment.AsInt);

            int staticOffset    = startOffset;
            int staticOffsetEnd = _type.GCStaticFieldSize.AsInt;
            int idx             = 0;

            while (staticOffset < staticOffsetEnd)
            {
                int writeTo = staticOffsetEnd;
                if (idx < sortedPreInitFields.Count)
                {
                    writeTo = sortedPreInitFields[idx].Field.Offset.AsInt;
                }

                // Emit the zero before the next preinitField
                builder.EmitZeros(writeTo - staticOffset);
                staticOffset = writeTo;

                // Emit a pointer reloc to the frozen data
                if (idx < sortedPreInitFields.Count)
                {
                    builder.EmitPointerReloc(factory.SerializedFrozenArray(sortedPreInitFields[idx]));
                    idx++;
                    staticOffset += factory.Target.PointerSize;
                }
            }

            builder.AddSymbol(node);

            return(builder.ToObjectData());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            // If the type has a class constructor, its non-GC statics section is prefixed
            // by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
            {
                int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
                int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
                builder.RequireInitialAlignment(alignmentRequired);

                Debug.Assert(classConstructorContextStorageSize >= GetClassConstructorContextSize(_type.Context.Target));

                // Add padding before the context if alignment forces us to do so
                builder.EmitZeros(classConstructorContextStorageSize - GetClassConstructorContextSize(_type.Context.Target));

                // Emit the actual StaticClassConstructionContext
                MethodDesc cctorMethod = _type.GetStaticConstructor();
                builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
                builder.EmitZeroPointer();
            }
            else
            {
                builder.RequireInitialAlignment(_type.NonGCStaticFieldAlignment.AsInt);
            }

            if (_sortedPreInitFields != null)
            {
                int staticOffsetBegin = builder.CountBytes;
                int staticOffsetEnd   = builder.CountBytes + _type.NonGCStaticFieldSize.AsInt;
                int staticOffset      = staticOffsetBegin;
                int idx = 0;

                while (staticOffset < staticOffsetEnd)
                {
                    int writeTo = staticOffsetEnd;
                    if (idx < _sortedPreInitFields.Count)
                    {
                        writeTo = staticOffsetBegin + _sortedPreInitFields[idx].Field.Offset.AsInt;
                    }

                    // Emit the zeros before the next preinitField
                    builder.EmitZeros(writeTo - staticOffset);
                    staticOffset = writeTo;

                    // Emit the data
                    if (idx < _sortedPreInitFields.Count)
                    {
                        _sortedPreInitFields[idx].WriteData(ref builder, factory);
                        idx++;
                        staticOffset = builder.CountBytes;
                    }
                }
            }
            else
            {
                builder.EmitZeros(_type.NonGCStaticFieldSize.AsInt);
            }

            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
 private void AlignNextObject(ref ObjectDataBuilder builder, NodeFactory factory)
 {
     builder.EmitZeros(AlignmentHelper.AlignUp(builder.CountBytes, factory.Target.PointerSize) - builder.CountBytes);
 }
Beispiel #13
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            // If the type has a class constructor, its non-GC statics section is prefixed
            // by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
            if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
            {
                int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
                int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
                builder.RequireInitialAlignment(alignmentRequired);

                Debug.Assert(classConstructorContextStorageSize >= GetClassConstructorContextSize(_type.Context.Target));

                // Add padding before the context if alignment forces us to do so
                builder.EmitZeros(classConstructorContextStorageSize - GetClassConstructorContextSize(_type.Context.Target));

                // Emit the actual StaticClassConstructionContext
                MethodDesc cctorMethod = _type.GetStaticConstructor();
                builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
                builder.EmitZeroPointer();
            }
            else
            {
                builder.RequireInitialAlignment(_type.NonGCStaticFieldAlignment.AsInt);
            }

            if (_preinitializationManager.IsPreinitialized(_type))
            {
                TypePreinit.PreinitializationInfo preinitInfo = _preinitializationManager.GetPreinitializationInfo(_type);
                int initialOffset = builder.CountBytes;
                foreach (FieldDesc field in _type.GetFields())
                {
                    if (!field.IsStatic || field.HasRva || field.IsLiteral || field.IsThreadStatic || field.HasGCStaticBase)
                    {
                        continue;
                    }

                    int padding = field.Offset.AsInt - builder.CountBytes + initialOffset;
                    Debug.Assert(padding >= 0);
                    builder.EmitZeros(padding);

                    TypePreinit.ISerializableValue val = preinitInfo.GetFieldValue(field);
                    int currentOffset = builder.CountBytes;
                    val.WriteFieldData(ref builder, factory);
                    Debug.Assert(builder.CountBytes - currentOffset == field.FieldType.GetElementSize().AsInt);
                }

                int pad = _type.NonGCStaticFieldSize.AsInt - builder.CountBytes + initialOffset;
                Debug.Assert(pad >= 0);
                builder.EmitZeros(pad);
            }
            else
            {
                builder.EmitZeros(_type.NonGCStaticFieldSize.AsInt);
            }

            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
Beispiel #14
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            // If the type has a class constructor, it's non-GC statics section is prefixed  
            // by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
            if (HasClassConstructorContext)
            {
                int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment, ClassConstructorContextAlignment);
                builder.RequireAlignment(alignmentRequired);

                Debug.Assert(((ISymbolNode)this).Offset >= ClassConstructorContextSize);

                // Add padding before the context if alignment forces us to do so
                builder.EmitZeros(((ISymbolNode)this).Offset - ClassConstructorContextSize);

                // Emit the actual StaticClassConstructionContext                
                var cctorMethod = _type.GetStaticConstructor();
                builder.EmitPointerReloc(factory.MethodEntrypoint(cctorMethod));
                builder.EmitZeroPointer();

                builder.DefinedSymbols.Add(_classConstructorContext);
            }
            else
            {
                builder.RequireAlignment(_type.NonGCStaticFieldAlignment);
            }

            builder.EmitZeros(_type.NonGCStaticFieldSize);
            builder.DefinedSymbols.Add(this);

            return builder.ToObjectData();
        }
Beispiel #15
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            // If the type has a class constructor, its non-GC statics section is prefixed  
            // by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
            {
                int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment, GetClassConstructorContextAlignment(_type.Context.Target));
                int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
                builder.RequireAlignment(alignmentRequired);
                
                Debug.Assert(classConstructorContextStorageSize >= GetClassConstructorContextSize(_type.Context.Target));

                // Add padding before the context if alignment forces us to do so
                builder.EmitZeros(classConstructorContextStorageSize - GetClassConstructorContextSize(_type.Context.Target));

                // Emit the actual StaticClassConstructionContext
                MethodDesc cctorMethod = _type.GetStaticConstructor();
                MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                if (cctorMethod != canonCctorMethod)
                    builder.EmitPointerReloc(factory.FatFunctionPointer(cctorMethod), FatFunctionPointerConstants.Offset);
                else
                    builder.EmitPointerReloc(factory.MethodEntrypoint(cctorMethod));
                builder.EmitZeroPointer();
            }
            else
            {
                builder.RequireAlignment(_type.NonGCStaticFieldAlignment);
            }

            builder.EmitZeros(_type.NonGCStaticFieldSize);
            builder.DefinedSymbols.Add(this);

            return builder.ToObjectData();
        }