Example #1
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();
                builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
                builder.EmitZeroPointer();
            }
            else
            {
                builder.RequireInitialAlignment(_type.NonGCStaticFieldAlignment.AsInt);
            }

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

            return(builder.ToObjectData());
        }
Example #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)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialAlignment(4);
            objData.AddSymbol(this);

            if (BuildSealedVTableSlots(factory, relocsOnly))
            {
                for (int i = 0; i < _sealedVTableEntries.Count; i++)
                {
                    MethodDesc  canonImplMethod = _sealedVTableEntries[i].GetCanonMethodTarget(CanonicalFormKind.Specific);
                    IMethodNode relocTarget     = factory.MethodEntrypoint(canonImplMethod, _sealedVTableEntries[i].OwningType.IsValueType);

                    if (factory.Target.SupportsRelativePointers)
                    {
                        objData.EmitReloc(relocTarget, RelocType.IMAGE_REL_BASED_RELPTR32);
                    }
                    else
                    {
                        objData.EmitPointerReloc(relocTarget);
                    }
                }
            }

            return(objData.ToObjectData());
        }
Example #4
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            Debug.Assert(MethodHasAssociatedData(factory, _methodNode));

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialAlignment(1);
            objData.AddSymbol(this);

            AssociatedDataFlags flags = AssociatedDataFlags.None;

            var flagsReservation = objData.ReserveByte();

            ISpecialUnboxThunkNode unboxThunkNode = _methodNode as ISpecialUnboxThunkNode;

            if (unboxThunkNode != null && unboxThunkNode.IsSpecialUnboxingThunk)
            {
                flags |= AssociatedDataFlags.HasUnboxingStubTarget;
                objData.EmitReloc(unboxThunkNode.GetUnboxingThunkTarget(factory), RelocType.IMAGE_REL_BASED_RELPTR32);
            }

            objData.EmitByte(flagsReservation, (byte)flags);

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

            objData.RequireInitialAlignment(4);
            objData.AddSymbol(this);

            if (BuildSealedVTableSlots(factory, relocsOnly))
            {
                for (int i = 0; i < _sealedVTableEntries.Count; i++)
                {
                    IMethodNode relocTarget = _sealedVTableEntries[i].GetTarget(factory, _type);

                    if (factory.Target.SupportsRelativePointers)
                    {
                        objData.EmitReloc(relocTarget, RelocType.IMAGE_REL_BASED_RELPTR32);
                    }
                    else
                    {
                        objData.EmitPointerReloc(relocTarget);
                    }
                }
            }

            return(objData.ToObjectData());
        }
Example #6
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 }));
            }

            // Zero out the dictionary so that we AV if someone tries to insert after we're done.
            _insertedSymbolsDictionary = null;

            var builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialAlignment(factory.Target.SupportsRelativePointers ? 4 : factory.Target.PointerSize);

            foreach (SymbolAndDelta symbolAndDelta in _insertedSymbols)
            {
                if (factory.Target.SupportsRelativePointers)
                {
                    // TODO: set low bit if the linkage of the symbol is IAT_PVALUE.
                    builder.EmitReloc(symbolAndDelta.Symbol, RelocType.IMAGE_REL_BASED_RELPTR32, symbolAndDelta.Delta);
                }
                else
                {
                    builder.EmitPointerReloc(symbolAndDelta.Symbol, symbolAndDelta.Delta);
                }
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);

            builder.AddSymbol(this);
            builder.AddSymbol(_endSymbol);

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

            // These need to be aligned the same as methods because they show up in same contexts
            builder.RequireInitialAlignment(factory.Target.MinimumFunctionAlignment);

            builder.AddSymbol(this);

            MethodDesc canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific);

            // Pointer to the canonical body of the method
            builder.EmitPointerReloc(factory.MethodEntrypoint(canonMethod, _isUnboxingStub));

            // Find out what's the context to use
            ISymbolNode contextParameter;

            if (canonMethod.RequiresInstMethodDescArg())
            {
                contextParameter = factory.MethodGenericDictionary(Method);
            }
            else
            {
                Debug.Assert(canonMethod.RequiresInstMethodTableArg());

                // Ask for a constructed type symbol because we need the vtable to get to the dictionary
                contextParameter = factory.ConstructedTypeSymbol(Method.OwningType);
            }

            // The next entry is a pointer to the pointer to the context to be used for the canonical method
            // TODO: in multi-module, this points to the import cell, and is no longer this weird pointer
            builder.EmitPointerReloc(factory.Indirection(contextParameter));

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

            // The interface dispatch cell has an alignment requirement of 2 * [Pointer size] as part of the
            // synchronization mechanism of the two values in the runtime.
            objData.RequireInitialAlignment(_targetMethod.Context.Target.PointerSize * 2);
            objData.AddSymbol(this);

            if (factory.Target.Architecture == TargetArchitecture.ARM)
            {
                objData.EmitPointerReloc(factory.InitialInterfaceDispatchStub);
            }
            else
            {
                objData.EmitPointerReloc(factory.ExternSymbol("RhpInitialDynamicInterfaceDispatch"));
            }

            if (factory.Target.Abi == TargetAbi.CoreRT)
            {
                // TODO: Enable Indirect Pointer for Interface Dispatch Cell. See https://github.com/dotnet/corert/issues/2542
                objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType),
                                         (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfacePointerOrMetadataToken);
            }
            else
            {
                if (factory.CompilationModuleGroup.ContainsType(_targetMethod.OwningType))
                {
                    objData.EmitReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), RelocType.IMAGE_REL_BASED_RELPTR32,
                                      (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfaceRelativePointer);
                }
                else
                {
                    objData.EmitReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), RelocType.IMAGE_REL_BASED_RELPTR32,
                                      (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsIndirectedInterfaceRelativePointer);
                }

                if (objData.TargetPointerSize == 8)
                {
                    // IMAGE_REL_BASED_RELPTR is a 32-bit relocation. However, the cell needs a full pointer
                    // width there since a pointer to the cache will be written into the cell. Emit additional
                    // 32 bits on targets whose pointer size is 64 bit.
                    objData.EmitInt(0);
                }
            }

            // End the run of dispatch cells
            objData.EmitZeroPointer();

            // Avoid consulting VTable slots until they're guaranteed complete during final data emission
            if (!relocsOnly)
            {
                objData.EmitNaturalInt(VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, _targetMethod));
            }

            return(objData.ToObjectData());
        }
Example #9
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // Emit a 4-byte integer flag with initial value of 0.
            // TODO: define it as "comdat select any" when multiple object files present.
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialAlignment(4);
            objData.AddSymbol(this);
            objData.EmitInt(0);
            return(objData.ToObjectData());
        }
Example #10
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            Debug.Assert(factory.Target.IsWindows);

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialAlignment(factory.Target.MinimumFunctionAlignment);
            objData.AddSymbol(this);

            return(objData.ToObjectData());
        }
Example #11
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());
        }
Example #12
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialAlignment(16);
            objData.AddSymbol(this);

            if (!relocsOnly)
            {
                EmitDispatchMap(ref objData, factory);
            }

            return(objData.ToObjectData());
        }
Example #13
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialAlignment(1);
            objData.AddSymbol(this);

            if (!relocsOnly)
            {
                _owner.ComputeOptionalEETypeFields(factory, relocsOnly: false);
                objData.EmitBytes(_owner.GetOptionalFieldsData());
            }

            return(objData.ToObjectData());
        }
Example #14
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);
     }
 }
        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());
        }
Example #16
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());
        }
        protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
        {
            if (relocsOnly)
            {
                return;
            }

            // The interface dispatch cell has an alignment requirement of 2 * [Pointer size] as part of the
            // synchronization mechanism of the two values in the runtime.
            builder.RequireInitialAlignment(factory.Target.PointerSize * 2);

            // This number chosen to be high enough that the cost of recording slot numbers is cheap.
            const int InterfaceDispatchCellRunLength = 32;

            const int NoSlot = -1;

            //
            // We emit the individual dispatch cells in groups. The purpose of the grouping is to save
            // us the number of slots we need to emit. The grouping looks like this:
            //
            // DispatchCell1
            // DispatchCell2
            // ...
            // DispatchCellN
            // Null
            // Slot of the above dispatch cells
            //
            int runLength   = 0;
            int currentSlot = NoSlot;

            foreach (InterfaceDispatchCellNode node in NodesList)
            {
                MethodDesc targetMethod = node.TargetMethod;
                int        targetSlot   = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, targetMethod, targetMethod.OwningType);
                if (currentSlot == NoSlot)
                {
                    // This is the first dispatch cell we're emitting
                    currentSlot = targetSlot;
                }
                else if (currentSlot != targetSlot || runLength == InterfaceDispatchCellRunLength)
                {
                    // Make sure we are sorted
                    Debug.Assert(targetSlot >= currentSlot);

                    // End the run of dispatch cells
                    builder.EmitZeroPointer();
                    builder.EmitNaturalInt(currentSlot);

                    currentSlot = targetSlot;
                    runLength   = 0;
                }

                node.InitializeOffsetFromBeginningOfArray(builder.CountBytes);
                node.EncodeData(ref builder, factory, relocsOnly);
                builder.AddSymbol(node);

                runLength++;
            }

            if (runLength > 0)
            {
                // End the run of dispatch cells
                builder.EmitZeroPointer();
                builder.EmitNaturalInt(currentSlot);
            }
        }
Example #19
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());
        }
Example #20
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();
                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());
        }