Пример #1
0
        public static unsafe Object CompilerAllocateGenerational
            (VTable vtable, Thread currentThread, UIntPtr bytes, uint alignment)
        {
            VTable.Assert((alignment == 4) ||
                          ((alignment == 8) && (UIntPtr.Size == 8)) ||
                          ((alignment == 8) && (PreHeader.Size == 4)),
                          "Unsupported object layout");
            VTable.Assert(UIntPtr.Size == PreHeader.Size,
                          "Unsupported preheader size");
            VTable.Assert
                (Util.IsAligned((uint)PreHeader.Size + (uint)PostHeader.Size,
                                alignment),
                "Unsupported header sizes");

            UIntPtr preHeaderAddr =
                MixinThread(currentThread).bumpAllocator.allocPtr;

            // allocPtr is only needed when alignment needs to be checked.  It
            // stores the beginning of the region to be allocation including
            // a possible alignment token.
            UIntPtr allocPtr = UIntPtr.Zero;

            if ((alignment == 8) && (UIntPtr.Size == 4))
            {
                allocPtr      = preHeaderAddr;
                preHeaderAddr = Util.Pad(preHeaderAddr, (UIntPtr)alignment);
            }

            UIntPtr bound    = preHeaderAddr + bytes;
            UIntPtr limitPtr =
                MixinThread(currentThread).bumpAllocator.zeroedLimit;

            if (bound <= limitPtr)
            {
                if ((alignment == 8) && (UIntPtr.Size == 4))
                {
                    // Store alignment token at allocPtr.  This will be where an
                    // alignment token should go if 'preHeaderAddr' was
                    // bumped...
                    Allocator.WriteAlignment(allocPtr);
                    // ... or the alignment token is where the object header
                    // should be.  This code zeroes the object header regardless
                    // and avoids a branch in this fast path.
                    *(UIntPtr *)preHeaderAddr = UIntPtr.Zero;
                }
                MixinThread(currentThread).bumpAllocator.allocPtr = bound;

                UIntPtr objAddr = preHeaderAddr + PreHeader.Size;
                Object  obj     = Magic.fromAddress(objAddr);
                obj.vtable = vtable;
                return(obj);
            }

            return(GC.AllocateObjectNoInline(vtable, currentThread));
        }