Beispiel #1
0
        internal override String AllocateString(int stringLength,
                                                Thread currentThread)
        {
            String result = base.AllocateString(stringLength, currentThread);

            if (VTable.enableGCProfiling)
            {
                ulong size = (ulong)
                             ObjectLayout.StringSize(vtable,
                                                     unchecked ((uint)(stringLength + 1)));
                RegisterNewObject(size);
            }
            return(result);
        }
Beispiel #2
0
        internal override String AllocateString(int stringLength,
                                                Thread currentThread)
        {
            VTable vtable =
                Magic.toRuntimeType(typeof(System.String)).classVtable;
            UIntPtr numBytes =
                ObjectLayout.StringSize(vtable,
                                        unchecked ((uint)(stringLength + 1)));
            UIntPtr stringAddr =
                AllocateObjectMemory(numBytes, unchecked ((uint)UIntPtr.Size),
                                     currentThread);
            String result = Magic.toString(Magic.fromAddress(stringAddr));

            CreateObject(result, vtable, currentThread);
            result.InitializeStringLength(stringLength);
            return(result);
        }
        UIntPtr VisitReferenceFieldsTemplate(ref ObjectDescriptor objDesc)
        {
            UIntPtr pointerTracking = objDesc.vtable.pointerTrackingMask;
            uint    objectTag       = (pointerTracking & 0xf);
            UIntPtr size;

            switch (objectTag)
            {
            case ObjectLayout.SPARSE_TAG: {
                UIntPtr *sparseObject = (UIntPtr *)objDesc.objectBase;
                size              = ObjectLayout.ObjectSize(objDesc.vtable);
                pointerTracking >>= 4;
                while (pointerTracking != 0)
                {
                    uint index = pointerTracking & 0xf;
                    pointerTracking >>= 4;
                    // The cast to int prevents C# from taking the
                    // index * sizeof(UIntPtr) to long:
                    UIntPtr *loc = sparseObject + (int)index;
                    this.Filter(loc, ref objDesc);
                }
                break;
            }

            case ObjectLayout.DENSE_TAG: {
                // skip vtable
                int      postHeaderSize = PostHeader.Size;
                UIntPtr *denseObject    = (UIntPtr *)
                                          (objDesc.objectBase + postHeaderSize);
                size              = ObjectLayout.ObjectSize(objDesc.vtable);
                pointerTracking >>= 4;
                while (pointerTracking != 0)
                {
                    if ((pointerTracking & ((UIntPtr)0x1)) != 0)
                    {
                        this.Filter(denseObject, ref objDesc);
                    }
                    pointerTracking >>= 1;
                    denseObject++;
                }
                break;
            }

            case ObjectLayout.PTR_VECTOR_TAG: {
                int  postHeaderSize = PostHeader.Size;
                uint length         = *(uint *)(objDesc.objectBase + postHeaderSize);
                size = ObjectLayout.ArraySize(objDesc.vtable, length);
                int      preHeaderSize  = PreHeader.Size;
                UIntPtr *elementAddress = (UIntPtr *)
                                          (objDesc.objectBase + objDesc.vtable.baseLength -
                                           preHeaderSize);
                for (uint i = 0; i < length; i++, elementAddress++)
                {
                    this.Filter(elementAddress, ref objDesc);
                }
                break;
            }

            case ObjectLayout.OTHER_VECTOR_TAG: {
                int  postHeaderSize = PostHeader.Size;
                uint length         = *(uint *)(objDesc.objectBase + postHeaderSize);
                size = ObjectLayout.ArraySize(objDesc.vtable, length);
                if (objDesc.vtable.arrayOf == StructuralType.Struct)
                {
                    // pretend the struct is boxed and account for the
                    // presence of the vtable field
                    VTable  elementVTable = objDesc.vtable.arrayElementClass;
                    UIntPtr elementMask   = elementVTable.pointerTrackingMask;
                    // A structure with no references will have a SPARSE
                    // descriptor with no offset values.
                    if (elementMask != (UIntPtr)ObjectLayout.SPARSE_TAG)
                    {
                        int     preHeaderSize  = PreHeader.Size;
                        UIntPtr elementAddress = (objDesc.objectBase +
                                                  objDesc.vtable.baseLength -
                                                  preHeaderSize -
                                                  postHeaderSize);
                        int elementSize = objDesc.vtable.arrayElementSize;
                        objDesc.vtable = elementVTable;
                        for (uint i = 0; i < length; i++)
                        {
                            objDesc.objectBase = elementAddress;
                            this.VisitReferenceFieldsTemplateNoInline(ref objDesc);
                            elementAddress += elementSize;
                        }
                    }
                }
                break;
            }

            case ObjectLayout.PTR_ARRAY_TAG: {
                int  postHeaderSize = PostHeader.Size;
                uint length         = *(uint *)(objDesc.objectBase + postHeaderSize +
                                                sizeof(uint));
                size = ObjectLayout.ArraySize(objDesc.vtable, length);
                int      preHeaderSize  = PreHeader.Size;
                UIntPtr *elementAddress = (UIntPtr *)
                                          (objDesc.objectBase + objDesc.vtable.baseLength -
                                           preHeaderSize);
                for (uint i = 0; i < length; i++, elementAddress++)
                {
                    this.Filter(elementAddress, ref objDesc);
                }
                break;
            }

            case ObjectLayout.OTHER_ARRAY_TAG: {
                int  postHeaderSize = PostHeader.Size;
                uint length         = *(uint *)(objDesc.objectBase + postHeaderSize +
                                                sizeof(uint));
                size = ObjectLayout.ArraySize(objDesc.vtable, length);
                if (objDesc.vtable.arrayOf == StructuralType.Struct)
                {
                    // pretend the struct is boxed and account for the
                    // presence of the PostHeader
                    VTable  elementVTable = objDesc.vtable.arrayElementClass;
                    UIntPtr elementMask   = elementVTable.pointerTrackingMask;
                    // A structure with no references will have a SPARSE
                    // descriptor with no offset values.
                    if (elementMask != (UIntPtr)ObjectLayout.SPARSE_TAG)
                    {
                        int     preHeaderSize  = PreHeader.Size;
                        int     elementSize    = objDesc.vtable.arrayElementSize;
                        UIntPtr elementAddress =
                            objDesc.objectBase + objDesc.vtable.baseLength -
                            preHeaderSize - postHeaderSize;
                        objDesc.vtable = elementVTable;
                        for (uint i = 0; i < length; i++)
                        {
                            objDesc.objectBase = elementAddress;
                            this.VisitReferenceFieldsTemplateNoInline(ref objDesc);
                            elementAddress += elementSize;
                        }
                    }
                }
                break;
            }

            case ObjectLayout.STRING_TAG: {
                int  postHeaderSize = PostHeader.Size;
                uint arrayLength    =
                    *(uint *)(objDesc.objectBase + postHeaderSize);
                size = ObjectLayout.StringSize(objDesc.vtable, arrayLength);
                break;
            }

            default: {
                // escape case
                VTable.Assert((objectTag & 0x1) == 0,
                              "ReferenceVisitor: (objectTag & 0x1) == 0");
                UIntPtr *largeObject = (UIntPtr *)objDesc.objectBase;
                size = ObjectLayout.ObjectSize(objDesc.vtable);
                int *pointerDescription = (int *)pointerTracking;
                int  count = *pointerDescription;
                for (int i = 1; i <= count; i++)
                {
                    UIntPtr *loc = largeObject + *(pointerDescription + i);
                    this.Filter(loc, ref objDesc);
                }
                break;
            }
            }
            return(size);
        }