/// <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]); } } }
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); } }
/// <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 } }