Ejemplo n.º 1
0
        public static void Cleanup()
        {
            if (!Enabled /*|| InsideGC*/)
            {
                return;
            }

            //try
            {
                InsideGC = true;

#if GC_TRACE
                int startNumObjs    = NumObjs;
                int startNumStrings = NumStrings;
#endif

                ObjectToCleanup *currObjToCleanupPtr = CleanupList;
                ObjectToCleanup *prevObjToCleanupPtr = null;
                while (currObjToCleanupPtr != null)
                {
                    GCHeader *objHeaderPtr = currObjToCleanupPtr->objHeaderPtr;
                    void *    objPtr       = currObjToCleanupPtr->objPtr;
                    if (objHeaderPtr->RefCount <= 0)
                    {
                        FlingOops.Object obj = (FlingOops.Object)Utilities.ObjectUtilities.GetObject(objPtr);
                        if (obj is FlingOops.String)
                        {
                            NumStrings--;
                        }

                        Heap.Free(objHeaderPtr);

                        NumObjs--;
                    }

                    prevObjToCleanupPtr = currObjToCleanupPtr;
                    currObjToCleanupPtr = currObjToCleanupPtr->prevPtr;
                    RemoveObjectToCleanup(prevObjToCleanupPtr);
                }

                InsideGC = false;

#if GC_TRACE
                PrintCleanupData(startNumObjs, startNumStrings);
#endif
            }
            //finally
            {
            }
        }
Ejemplo n.º 2
0
        public static void IncrementRefCount(FlingOops.Object anObj)
        {
            if (!Enabled /*|| InsideGC*/ || anObj == null)
            {
                return;
            }

            InsideGC = true;

            byte *objPtr = (byte *)Utilities.ObjectUtilities.GetHandle(anObj);

            _IncrementRefCount(objPtr);

            InsideGC = false;
        }
Ejemplo n.º 3
0
        public static void DecrementRefCount(FlingOops.Object anObj, bool overrideInside)
        {
            if (!Enabled /*|| (InsideGC && !overrideInside)*/ || anObj == null)
            {
                return;
            }

            if (!overrideInside)
            {
                InsideGC = true;
            }

            byte *objPtr = (byte *)Utilities.ObjectUtilities.GetHandle(anObj);

            _DecrementRefCount(objPtr);

            if (!overrideInside)
            {
                InsideGC = false;
            }
        }
Ejemplo n.º 4
0
        public static void _DecrementRefCount(byte *objPtr)
        {
            if ((uint)objPtr < (uint)sizeof(GCHeader))
            {
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("Error! GC can't decrement ref count of an object in low memory.");
                BasicConsole.DelayOutput(5);
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }

            GCHeader *gcHeaderPtr = (GCHeader *)(objPtr - sizeof(GCHeader));

            if (CheckSignature(gcHeaderPtr))
            {
                gcHeaderPtr->RefCount--;

                //If the ref count goes below 0 then there was a circular reference somewhere.
                //  In actuality we don't care we can just only do cleanup when the ref count is
                //  exactly 0.
                if (gcHeaderPtr->RefCount == 0)
                {
#if GC_TRACE
                    BasicConsole.WriteLine("Cleaning up object...");
#endif

                    FlingOops.Object obj = (FlingOops.Object)Utilities.ObjectUtilities.GetObject(objPtr);
                    if (obj is FlingOops.Array)
                    {
                        //Decrement ref count of elements
                        FlingOops.Array arr = (FlingOops.Array)obj;
                        if (!arr.elemType.IsValueType)
                        {
                            FlingOops.Object[] objArr = (FlingOops.Object[])Utilities.ObjectUtilities.GetObject(objPtr);
                            for (int i = 0; i < arr.length; i++)
                            {
                                DecrementRefCount(objArr[i], true);
                            }
                        }
                    }
                    //Cleanup fields
                    FieldInfo *FieldInfoPtr = obj._Type.FieldTablePtr;
                    //Loop through all fields. The if-block at the end handles moving to parent
                    //  fields.
                    while (FieldInfoPtr != null)
                    {
                        if (FieldInfoPtr->Size > 0)
                        {
                            FlingOops.Type fieldType = (FlingOops.Type)Utilities.ObjectUtilities.GetObject(FieldInfoPtr->FieldType);
                            if (!fieldType.IsValueType &&
                                !fieldType.IsPointer)
                            {
                                byte *           fieldPtr    = objPtr + FieldInfoPtr->Offset;
                                FlingOops.Object theFieldObj = (FlingOops.Object)Utilities.ObjectUtilities.GetObject(fieldPtr);

                                DecrementRefCount(theFieldObj, true);

#if GC_TRACE
                                BasicConsole.WriteLine("Cleaned up field.");
#endif
                            }

                            FieldInfoPtr++;
                        }

                        if (FieldInfoPtr->Size == 0)
                        {
                            FieldInfoPtr = (FieldInfo *)FieldInfoPtr->FieldType;
                        }
                    }

#if GC_TRACE
                    BasicConsole.WriteLine("Adding object to clean up...");
#endif
                    AddObjectToCleanup(gcHeaderPtr, objPtr);

#if GC_TRACE
                    BasicConsole.WriteLine("Completed decrement ref count processing.");
#endif
                }
            }
        }
Ejemplo n.º 5
0
 public static void DecrementRefCount(FlingOops.Object anObj)
 {
     DecrementRefCount(anObj, false);
 }