Ejemplo n.º 1
0
        public GCStaticsNode(MetadataType type, PreinitializationManager preinitManager)
        {
            Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific));
            _type = type;

            if (preinitManager.IsPreinitialized(type))
            {
                _preinitializationInfo = preinitManager.GetPreinitializationInfo(_type);
            }
        }
Ejemplo n.º 2
0
 public GCStaticsPreInitDataNode(TypePreinit.PreinitializationInfo preinitializationInfo)
 {
     Debug.Assert(!preinitializationInfo.Type.IsCanonicalSubtype(CanonicalFormKind.Specific));
     _preinitializationInfo = preinitializationInfo;
 }
Ejemplo n.º 3
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());
        }