Ejemplo n.º 1
0
        internal static Object Allocate(VTable vtable, uint count)
        {
            UIntPtr numBytes   = ObjectLayout.ArraySize(vtable, count);
            UIntPtr objectAddr = AllocateBlock(numBytes, vtable.baseAlignment);
            Array   result     = Magic.toArray(Magic.fromAddress(objectAddr));

#if REFERENCE_COUNTING_GC
            uint refState = vtable.isAcyclicRefType ?
                            (ReferenceCountingCollector.
                             acyclicFlagMask | 2) : 2;
            result.REF_STATE = refState &
                               ~ReferenceCountingCollector.countingONFlagMask;
#elif DEFERRED_REFERENCE_COUNTING_GC
            uint refState = vtable.isAcyclicRefType ?
                            (DeferredReferenceCountingCollector.
                             acyclicFlagMask |
                             DeferredReferenceCountingCollector.
                             markFlagMask) :
                            DeferredReferenceCountingCollector.
                            markFlagMask;
            result.REF_STATE = refState &
                               ~DeferredReferenceCountingCollector.countingONFlagMask;
#endif
            Barrier.BootstrapInitObject(result, vtable);
            result.InitializeVectorLength((int)count);
            return(result);
        }
Ejemplo n.º 2
0
        public static void Initialize()
        {
            Object plcLinkObj = BootstrapMemory.Allocate(typeof(PLCLink));

            firstPLCLink =
                (PLCLink *)(Magic.addressOf(plcLinkObj) + PostHeader.Size);
            plcListVtable     = ((RuntimeType)typeof(PLCLink[])).classVtable;
            plcListChunkBytes =
                ObjectLayout.ArraySize(plcListVtable, plcListChunkLength);
        }
Ejemplo n.º 3
0
        internal override Array AllocateVector(VTable vtable,
                                               int numElements,
                                               Thread currentThread)
        {
            UIntPtr numBytes =
                ObjectLayout.ArraySize(vtable, unchecked ((uint)numElements));
            UIntPtr vectorAddr =
                AllocateObjectMemory(numBytes, vtable.baseAlignment,
                                     currentThread);
            Array result = Magic.toArray(Magic.fromAddress(vectorAddr));

            CreateObject(result, vtable, currentThread);
            result.InitializeVectorLength(numElements);
            return(result);
        }
Ejemplo n.º 4
0
        internal override Array AllocateVector(VTable vtable,
                                               int numElements,
                                               Thread currentThread)
        {
            Array result =
                base.AllocateVector(vtable, numElements, currentThread);

            if (VTable.enableGCProfiling)
            {
                ulong size = (ulong)
                             ObjectLayout.ArraySize(vtable,
                                                    unchecked ((uint)numElements));
                RegisterNewObject(size);
            }
            return(result);
        }
Ejemplo n.º 5
0
        public static unsafe void Initialize()
        {
            maxEntries = 1 << 16;
            VTable UIntPtrArrayVtable =
                ((RuntimeType)typeof(UIntPtr[])).classVtable;

            tableSize =
                ObjectLayout.ArraySize(UIntPtrArrayVtable, maxEntries);

            // Allocate a pool for ZCT
            BumpAllocator entryPool = new BumpAllocator(PageType.NonGC);
            UIntPtr       memStart  = MemoryManager.AllocateMemory(tableSize);

            entryPool.SetZeroedRange(memStart, tableSize);
            PageManager.SetStaticDataPages(memStart, tableSize);

            // Initialize ZCT
            zeroCountTable = (UIntPtr[])
                             DeferredReferenceCountingCollector.
                             AllocateArray(ref entryPool,
                                           UIntPtrArrayVtable,
                                           tableSize);
            VTable.Assert(zeroCountTable != null,
                          @"zeroCountTable != null");

            *(uint *)(Magic.addressOf(zeroCountTable) + PostHeader.Size) =
                maxEntries;
            VTable.Assert(zeroCountTable.Length == maxEntries,
                          @"zeroCountTable.Length == maxEntries");

            // Build ZCT freeEntries list
            freeHead = 1;
            for (uint i = 1; i < maxEntries - 1; i++)
            {
                zeroCountTable[i] = (UIntPtr)(((i + 1) << 2) | 0x01);
            }
            zeroCountTable[maxEntries - 1] = (UIntPtr)0x01;

            zctGarbagePicker =
                (ZCTGarbagePicker)BootstrapMemory.
                Allocate(typeof(ZCTGarbagePicker));
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        internal static unsafe bool AccumulateRCUpdates(String methodName,
                                                        int methodIndex,
                                                        uint maxIndex,
                                                        AcctRecord rec)
        {
            VTable.Assert(RCCollector.ProfilingMode,
                          @"RCCollector.ProfilingMode");

            // Return if the page table hasn't been set up yet.
            if (PageTable.pageTableCount == UIntPtr.Zero)
            {
                return(false);
            }

            if (methods == null)
            {
                // Allocate up front storage for the accounting records.
                //
                // This is requisitioned directly from the memory
                // manager. Care should be taken to ensure that
                // AccumulateRCUpdates does not indirectly call
                // methods that may have compiler-inserted RC updates.
                VTable vtable =
                    ((RuntimeType)typeof(AcctRecord[])).classVtable;
                UIntPtr size =
                    ObjectLayout.ArraySize(vtable, maxIndex + 1);

                BumpAllocator profileData =
                    new BumpAllocator(PageType.NonGC);
                UIntPtr profileDataStart =
                    MemoryManager.AllocateMemory(size);
                profileData.SetRange(profileDataStart, size);
                PageManager.SetStaticDataPages(profileDataStart, size);

                methods =
                    (AcctRecord[])Allocate(ref profileData, vtable, size);
                VTable.Assert(methods != null,
                              @"methods != null");

                *(uint *)(Magic.addressOf(methods) +
                          PostHeader.Size) = maxIndex + 1;
            }

            VTable.Assert(methods.Length == maxIndex + 1,
                          @"methods.Length == maxIndex+1");

            if (methods[methodIndex].methodName == null)
            {
                methodNames[methodIndex].methodName = methodName;
            }
            // Not "methodNames[methodIndex].methodName == methodName"
            // because the Equality operator carries compiler-inserted
            // RC updates!
            VTable.Assert(Magic.addressOf(methodNames[methodIndex].
                                          methodName) ==
                          Magic.addressOf(methodName),
                          @"Magic.addressOf(methodNames[methodIndex].
                                          methodName) ==
                        Magic.addressOf(methodName)");

            methods[methodIndex] += rec;

            return(true);
        }