Пример #1
0
        /// <summary>
        /// Marks all objects referenced
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="type"></param>
        public static void SweepTypedObject(uint *obj, uint type)
        {
            if (obj == null)
            {
                return;
            }
            uint fields  = VTablesImpl.GetGCFieldCount(type);
            var  offsets = VTablesImpl.GetGCFieldOffsets(type);
            var  types   = VTablesImpl.GetGCFieldTypes(type);

            for (int i = 0; i < fields; i++)
            {
                if (!VTablesImpl.IsValueType(types[i]))
                {
                    var location = (uint *)((byte *)obj + offsets[i]) + 1; // +1 since we are only using 32bits from the 64bit
                    if (*location != 0)                                    // Check if its null
                    {
                        location = *(uint **)location;
                        if (RAT.GetPageType(location) == RAT.PageType.HeapSmall)
                        {
                            MarkAndSweepObject(location);
                        }
                    }
                }
                else if (VTablesImpl.IsStruct(types[i]))
                {
                    var obj1 = (uint *)((byte *)obj + offsets[i]);
                    SweepTypedObject(obj1, types[i]);
                }
            }
        }
Пример #2
0
 private static bool ContainsReference(uint mType)
 {
     if (!VTablesImpl.IsValueType(mType))
     {
         return(true);
     }
     else if (VTablesImpl.IsStruct(mType))
     {
         var fields = VTablesImpl.GetGCFieldTypes(mType);
         for (int i = 0; i < fields.Length; i++)
         {
             if (ContainsReference(fields[i]))
             {
                 return(true);
             }
         }
         return(false);
     }
     else
     {
         return(false);
     }
 }
Пример #3
0
        /// <summary>
        /// Marks a GC managed object as referenced and recursivly marks child objects as well
        /// </summary>
        /// <param name="aPtr"></param>
        public static void MarkAndSweepObject(void *aPtr)
        {
            var gcPointer = (ObjectGCStatus *)aPtr;

            if ((gcPointer[-1] & ObjectGCStatus.Hit) == ObjectGCStatus.Hit)
            {
                return; // we already hit this object
            }

            // Mark
            gcPointer[-1] |= ObjectGCStatus.Hit;

            // Sweep

            uint *obj = (uint *)aPtr;

            // Check what we are dealing with
            if (*(obj + 1) == (uint)ObjectUtils.InstanceTypeEnum.NormalObject)
            {
                if (_StringType == 0)
                {
                    _StringType = GetStringTypeID();
                }
                var type = *obj;
                // Deal with strings first
                if (type == _StringType)
                {
                    return; // we are done since they dont hold any reference to fields
                }

                SweepTypedObject(obj, type);
            }
            else if (*(obj + 1) == (uint)ObjectUtils.InstanceTypeEnum.Array)
            {
                var elementType = *obj;
                var length      = *(obj + 2);
                var size        = *(obj + 3);
                if (VTablesImpl.IsValueType(elementType))
                {
                    if (VTablesImpl.IsStruct(elementType))
                    {
                        for (int i = 0; i < length; i++)
                        {
                            var location = (uint *)((byte *)obj + size * i) + 4;
                            SweepTypedObject(location, elementType);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < length; i++)
                    {
                        var location = (uint *)((byte *)obj + size * i) + 4 + 1;
                        if (*location != 0)
                        {
                            location = *(uint **)location;
                            if (RAT.GetPageType(location) == RAT.PageType.HeapSmall) // so we dont try free string literals
                            {
                                MarkAndSweepObject(location);
                            }
                        }
                    }
                }
            }
            else if (*(obj + 1) == (uint)ObjectUtils.InstanceTypeEnum.BoxedValueType)
            {
                // do nothing
            }
        }