Exemplo n.º 1
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("Cleaned up object.");
#endif

                    Testing2.Object obj = (Testing2.Object)Utilities.ObjectUtilities.GetObject(objPtr);
                    if (obj is Testing2.Array)
                    {
                        //Decrement ref count of elements
                        Testing2.Array arr = (Testing2.Array)obj;
                        if (!arr.elemType.IsValueType)
                        {
                            Testing2.Object[] objArr = (Testing2.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)
                        {
                            Testing2.Type fieldType = (Testing2.Type)Utilities.ObjectUtilities.GetObject(FieldInfoPtr->FieldType);
                            if (!fieldType.IsValueType &&
                                !fieldType.IsPointer)
                            {
                                byte *          fieldPtr    = objPtr + FieldInfoPtr->Offset;
                                Testing2.Object theFieldObj = (Testing2.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;
                        }
                    }

                    AddObjectToCleanup(gcHeaderPtr, objPtr);
                }
            }
        }
Exemplo n.º 2
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.");

                uint* basePtr = (uint*)ExceptionMethods.BasePointer;
                // Go up the linked-list of stack frames to (hopefully) the outermost caller
                basePtr = (uint*)*(basePtr); // DecrementRefCount(x, y)
                basePtr = (uint*)*(basePtr); // DecrementRefCount(x)
                uint retAddr = *(basePtr + 1);
                uint objAddr = (uint)objPtr;
                String msgStr = "Caller: 0x        , Object: 0x        ";
                // Object: 37
                // Caller: 17
                ExceptionMethods.FillString(retAddr, 17, msgStr);
                ExceptionMethods.FillString(objAddr, 37, msgStr);
                BasicConsole.WriteLine(msgStr);

                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
                    if (OutputTrace)
                    {
                        BasicConsole.WriteLine("Cleaned up object.");
                    }
#endif

                    FOS_System.Object obj = (FOS_System.Object)Utilities.ObjectUtilities.GetObject(objPtr);
                    if (obj is FOS_System.Array)
                    {
                        //Decrement ref count of elements
                        FOS_System.Array arr = (FOS_System.Array)obj;
                        if (!arr.elemType.IsValueType)
                        {
                            FOS_System.Object[] objArr = (FOS_System.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)
                        {
                            FOS_System.Type fieldType = (FOS_System.Type)Utilities.ObjectUtilities.GetObject(FieldInfoPtr->FieldType);
                            if (!fieldType.IsValueType &&
                                !fieldType.IsPointer)
                            {
                                byte* fieldPtr = objPtr + FieldInfoPtr->Offset;
                                FOS_System.Object theFieldObj = (FOS_System.Object)Utilities.ObjectUtilities.GetObject(fieldPtr);
                                
                                DecrementRefCount(theFieldObj, true);

#if GC_TRACE
                                if (OutputTrace)
                                {
                                    BasicConsole.WriteLine("Cleaned up field.");
                                }
#endif
                            }
                            
                            FieldInfoPtr++;
                        }

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

                    AddObjectToCleanup(gcHeaderPtr, objPtr);
                }
            }
        }