Пример #1
0
        private static void AddObjectToCleanup(GCHeader *objHeaderPtr, void *objPtr)
        {
            EnterCritical("AddObjectToCleanup");

            try
            {
                ObjectToCleanup *newObjToCleanupPtr = (ObjectToCleanup *)Heap.AllocZeroed((uint)sizeof(ObjectToCleanup), "GC : AddObjectToCleanup");
                newObjToCleanupPtr->objHeaderPtr = objHeaderPtr;
                newObjToCleanupPtr->objPtr       = objPtr;

                if (CleanupList != null)
                {
                    newObjToCleanupPtr->prevPtr = CleanupList;
                    CleanupList->nextPtr        = newObjToCleanupPtr;
                }
                else
                {
                    newObjToCleanupPtr->prevPtr = null;
                    newObjToCleanupPtr->nextPtr = null;
                }

                CleanupList = newObjToCleanupPtr;
            }
            finally
            {
                ExitCritical();
            }
        }
Пример #2
0
 public static unsafe bool CheckSignature(GCHeader* headerPtr)
 {
     bool OK = headerPtr->Sig1 == 0x5C0EADE2U;
     OK = OK && headerPtr->Sig2 == 0x5C0EADE2U;
     OK = OK && headerPtr->Checksum == 0xB81D5BC4U;
     return OK;
 }
Пример #3
0
        public static void *NewObj(Testing2.Type theType)
        {
            if (!Enabled)
            {
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine("Warning! GC returning null pointer because GC not enabled.");
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);

                return(null);
            }

            //try
            //{
            InsideGC = true;

            //Alloc space for GC header that prefixes object data
            //Alloc space for new object

            uint totalSize = theType.Size;

            totalSize += (uint)sizeof(GCHeader);

            GCHeader *newObjPtr = (GCHeader *)Heap.AllocZeroed(totalSize, "GC : NewObject");

            if ((UInt32)newObjPtr == 0)
            {
                InsideGC = false;

                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("Error! GC can't create a new object because the heap returned a null pointer.");
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);

                return(null);
            }

            NumObjs++;

            //Initialise the GCHeader
            SetSignature(newObjPtr);
            newObjPtr->RefCount = 1;
            //Initialise the object _Type field
            Testing2.ObjectWithType newObj = (Testing2.ObjectWithType)Utilities.ObjectUtilities.GetObject(newObjPtr + 1);
            newObj._Type = theType;

            //Move past GCHeader
            byte *newObjBytePtr = (byte *)(newObjPtr + 1);

            InsideGC = false;

            return(newObjBytePtr);
            //}
            //finally
            //{
            //}
        }
Пример #4
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)
                    {
                        Testing2.Object obj = (Testing2.Object)Utilities.ObjectUtilities.GetObject(objPtr);
                        if (obj is Testing2.String)
                        {
                            NumStrings--;
                        }

                        Heap.Free(objHeaderPtr);

                        NumObjs--;
                    }

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

                InsideGC = false;

#if GC_TRACE
                PrintCleanupData(startNumObjs, startNumStrings);
#endif
            }
            //finally
            {
            }
        }
Пример #5
0
        private static void AddObjectToCleanup(GCHeader *objHeaderPtr, void *objPtr)
        {
            //try
            {
                ObjectToCleanup *newObjToCleanupPtr = (ObjectToCleanup *)Heap.Alloc((uint)sizeof(ObjectToCleanup), "GC : AddObjectToCleanup");
                newObjToCleanupPtr->objHeaderPtr = objHeaderPtr;
                newObjToCleanupPtr->objPtr       = objPtr;

                newObjToCleanupPtr->prevPtr = CleanupList;
                CleanupList->nextPtr        = newObjToCleanupPtr;

                CleanupList = newObjToCleanupPtr;
            }
            //finally
            {
            }
        }
Пример #6
0
 private static void RemoveObjectToCleanup(GCHeader *objHeaderPtr)
 {
     //try
     {
         ObjectToCleanup *currObjToCleanupPtr = CleanupList;
         while (currObjToCleanupPtr != null)
         {
             if (currObjToCleanupPtr->objHeaderPtr == objHeaderPtr)
             {
                 RemoveObjectToCleanup(currObjToCleanupPtr);
                 return;
             }
             currObjToCleanupPtr = currObjToCleanupPtr->prevPtr;
         }
     }
     //finally
     {
     }
 }
Пример #7
0
        private static void RemoveObjectToCleanup(GCHeader *objHeaderPtr)
        {
            EnterCritical("RemoveObjectToCleanup");

            try
            {
                ObjectToCleanup *currObjToCleanupPtr = CleanupList;
                while (currObjToCleanupPtr != null)
                {
                    if (currObjToCleanupPtr->objHeaderPtr == objHeaderPtr)
                    {
                        RemoveObjectToCleanup(currObjToCleanupPtr);
                        return;
                    }
                    currObjToCleanupPtr = currObjToCleanupPtr->prevPtr;
                }
            }
            finally
            {
                ExitCritical();
            }
        }
Пример #8
0
        public static void _IncrementRefCount(byte* objPtr)
        {
            if ((uint)objPtr < (uint)sizeof(GCHeader))
            {
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("Error! GC can't increment 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);    // Frame of IncrementRefCount(x)
                uint retAddr = *(basePtr + 1);  // Caller of IncrementRefCount(x)
                basePtr = (uint*)*(basePtr);    // Frame of caller of IncrementRefCount(x)
                uint ret2Addr = *(basePtr + 1); // Caller of caller of IncrementRefCount(x)
                uint objAddr = (uint)objPtr;
                String msgStr = "Caller: 0x        , Object: 0x        , PCaller: 0x        ";
                // Object: 37
                // Caller: 17
                // PCaller: 58
                ExceptionMethods.FillString(retAddr, 17, msgStr);
                ExceptionMethods.FillString(objAddr, 37, msgStr);
                ExceptionMethods.FillString(ret2Addr, 58, msgStr);
                BasicConsole.WriteLine(msgStr);

                BasicConsole.DelayOutput(5);
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }
            
            objPtr -= sizeof(GCHeader);
            GCHeader* gcHeaderPtr = (GCHeader*)objPtr;
            if (CheckSignature(gcHeaderPtr))
            {
                gcHeaderPtr->RefCount++;

                if (gcHeaderPtr->RefCount > 0)
                {
                    RemoveObjectToCleanup(gcHeaderPtr);
                }
            }
        }
Пример #9
0
        public static void _IncrementRefCount(byte *objPtr)
        {
            if ((uint)objPtr < (uint)sizeof(GCHeader))
            {
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.WriteLine("Error! GC can't increment ref count of an object in low memory.");
                BasicConsole.DelayOutput(5);
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }

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

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

                if (gcHeaderPtr->RefCount > 0)
                {
                    RemoveObjectToCleanup(gcHeaderPtr);
                }
            }
        }
Пример #10
0
 public static void SetSignature(GCHeader *headerPtr)
 {
     headerPtr->Sig1     = 0x5C0EADE2U;
     headerPtr->Sig2     = 0x5C0EADE2U;
     headerPtr->Checksum = 0xB81D5BC4U;
 }
Пример #11
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);
                }
            }
        }
Пример #12
0
        public static void *NewString(int length)
        {
            if (!Enabled)
            {
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine("Warning! GC returning null pointer because GC not enabled.");
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);

                return(null);
            }

            //try
            {
                if (length < 0)
                {
                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("Error! GC can't create a new string because \"length\" is less than 0.");
                    BasicConsole.DelayOutput(5);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    return(null);
                    //ExceptionMethods.Throw_OverflowException();
                }

                InsideGC = true;

                //Alloc space for GC header that prefixes object data
                //Alloc space for new string object
                //Alloc space for new string chars

                uint totalSize = ((Testing2.Type) typeof(Testing2.String)).Size;
                totalSize += /*char size in bytes*/ 2 * (uint)length;
                totalSize += (uint)sizeof(GCHeader);

                GCHeader *newObjPtr = (GCHeader *)Heap.AllocZeroed(totalSize, "GC : NewString");

                if ((UInt32)newObjPtr == 0)
                {
                    InsideGC = false;

                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("Error! GC can't create a new string because the heap returned a null pointer.");
                    BasicConsole.DelayOutput(10);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    return(null);
                }

                NumObjs++;
                NumStrings++;

                //Initialise the GCHeader
                SetSignature(newObjPtr);
                //RefCount to 0 initially because of Testing2.String.New should be used
                //      - In theory, New should be called, creates new string and passes it back to caller
                //        Caller is then required to store the string in a variable resulting in inc.
                //        ref count so ref count = 1 in only stored location.
                //        Caller is not allowed to just "discard" (i.e. use Pop IL op or C# that generates
                //        Pop IL op) so ref count will always at some point be incremented and later
                //        decremented by managed code. OR the variable will stay in a static var until
                //        the OS exits...

                newObjPtr->RefCount = 0;

                Testing2.String newStr = (Testing2.String)Utilities.ObjectUtilities.GetObject(newObjPtr + 1);
                newStr._Type  = (Testing2.Type) typeof(Testing2.String);
                newStr.length = length;

                //Move past GCHeader
                byte *newObjBytePtr = (byte *)(newObjPtr + 1);

                InsideGC = false;

                return(newObjBytePtr);
            }
            //finally
            {
                //ExitCritical();
            }
        }
Пример #13
0
        public static void *NewArr(int length, Testing2.Type elemType)
        {
            if (!Enabled)
            {
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine("Warning! GC returning null pointer because GC not enabled.");
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);

                return(null);
            }

            //try
            {
                if (length < 0)
                {
                    UART.Write("length < 0. Overflow exception.");
                    return(null);
                    //ExceptionMethods.Throw_OverflowException();
                }

                InsideGC = true;

                //Alloc space for GC header that prefixes object data
                //Alloc space for new array object
                //Alloc space for new array elems

                uint totalSize = ((Testing2.Type) typeof(Testing2.Array)).Size;
                if (elemType.IsValueType)
                {
                    totalSize += elemType.Size * (uint)length;
                }
                else
                {
                    totalSize += elemType.StackSize * (uint)length;
                }
                totalSize += (uint)sizeof(GCHeader);

                GCHeader *newObjPtr = (GCHeader *)Heap.AllocZeroed(totalSize, "GC : NewArray");

                if ((UInt32)newObjPtr == 0)
                {
                    InsideGC = false;

                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("Error! GC can't create a new array because the heap returned a null pointer.");
                    BasicConsole.DelayOutput(10);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    return(null);
                }

                NumObjs++;

                //Initialise the GCHeader
                SetSignature(newObjPtr);
                newObjPtr->RefCount = 1;

                Testing2.Array newArr = (Testing2.Array)Utilities.ObjectUtilities.GetObject(newObjPtr + 1);
                newArr._Type    = (Testing2.Type) typeof(Testing2.Array);
                newArr.length   = length;
                newArr.elemType = elemType;

                //Move past GCHeader
                byte *newObjBytePtr = (byte *)(newObjPtr + 1);

                InsideGC = false;

                return(newObjBytePtr);
            }
            //finally
            {
            }
        }
Пример #14
0
        public static void Cleanup()
        {
            if (!Enabled /*|| InsideGC*/)
            {
                return;
            }

            EnterCritical("Cleanup");

            try
            {
                InsideGC = true;

#if GC_TRACE
                int startNumObjs    = NumObjs;
                int startNumStrings = NumStrings;
#endif
                if (OutputTrace)
                {
                    BasicConsole.WriteLine(" > Inside GC & Cleaning...");
                }

                ObjectToCleanup *currObjToCleanupPtr = CleanupList;
                ObjectToCleanup *prevObjToCleanupPtr = null;

                if (OutputTrace)
                {
                    BasicConsole.WriteLine(" > Got list...");
                }

                while (currObjToCleanupPtr != null)
                {
                    if (OutputTrace)
                    {
                        BasicConsole.WriteLine(" > Item not null.");

                        FOS_System.String str1 = " > Item: 0x        ";
                        FOS_System.String str2 = " > Prev: 0x        ";
                        ExceptionMethods.FillString((uint)currObjToCleanupPtr, 18, str1);
                        ExceptionMethods.FillString((uint)currObjToCleanupPtr->prevPtr, 18, str2);
                        BasicConsole.WriteLine(str1);
                        BasicConsole.WriteLine(str2);
                    }

                    GCHeader *objHeaderPtr = currObjToCleanupPtr->objHeaderPtr;
                    void *    objPtr       = currObjToCleanupPtr->objPtr;

                    if (OutputTrace)
                    {
                        BasicConsole.WriteLine(" > Got object handles.");
                    }

                    if (objHeaderPtr->RefCount <= 0)
                    {
                        if (OutputTrace)
                        {
                            BasicConsole.WriteLine("   > Ref count zero or lower.");
                        }

                        FOS_System.Object obj = (FOS_System.Object)Utilities.ObjectUtilities.GetObject(objPtr);

                        if (OutputTrace)
                        {
                            BasicConsole.WriteLine("   > Got object.");
                        }

                        if (obj is FOS_System.String)
                        {
                            if (OutputTrace)
                            {
                                BasicConsole.WriteLine("   > (It's a string).");
                            }

                            NumStrings--;
                        }
                        else
                        {
                            if (OutputTrace)
                            {
                                BasicConsole.WriteLine("   > (It's NOT a string).");
                            }

                            NumObjs--;
                        }

                        if (OutputTrace)
                        {
                            BasicConsole.WriteLine("   > About to free object...");
                        }

                        Heap.Free(objHeaderPtr);

                        if (OutputTrace)
                        {
                            BasicConsole.WriteLine("   > Object freed.");
                        }

                        if (OutputTrace)
                        {
                            BasicConsole.WriteLine("   > Done.");
                        }
                    }

                    if (OutputTrace)
                    {
                        BasicConsole.WriteLine(" > Shifting to next item...");
                    }

                    prevObjToCleanupPtr = currObjToCleanupPtr;
                    currObjToCleanupPtr = currObjToCleanupPtr->prevPtr;

                    if (OutputTrace)
                    {
                        BasicConsole.WriteLine(" > Removing object to cleanup...");
                    }

                    RemoveObjectToCleanup(prevObjToCleanupPtr);

                    if (OutputTrace)
                    {
                        BasicConsole.WriteLine(" > Done.");
                        BasicConsole.WriteLine(" > Loop back...");
                    }
                }

                InsideGC = false;

#if GC_TRACE
                if (OutputTrace)
                {
                    PrintCleanupData(startNumObjs, startNumStrings);
                }
#endif
            }
            finally
            {
                ExitCritical();
            }
        }
Пример #15
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);
                }
            }
        }
Пример #16
0
        public static void* NewObj(FOS_System.Type theType)
        {
            if (!Enabled)
            {
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine("Warning! GC returning null pointer because GC not enabled.");
                BasicConsole.Write("Last disabler: ");
                BasicConsole.WriteLine(lastDisabler);
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);

                return null;
            }

#if GC_TRACE
            if (OutputTrace)
            {
                BasicConsole.WriteLine("NewObj");
            }
#endif

            EnterCritical("NewObj");

            try
            {
                InsideGC = true;

                //Alloc space for GC header that prefixes object data
                //Alloc space for new object

                uint totalSize = theType.Size;
                totalSize += (uint)sizeof(GCHeader);

                GCHeader* newObjPtr = (GCHeader*)Heap.AllocZeroed(totalSize, "GC : NewObject");

                if ((UInt32)newObjPtr == 0)
                {
                    InsideGC = false;

                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("Error! GC can't create a new object because the heap returned a null pointer.");
                    BasicConsole.DelayOutput(10);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    return null;
                }

                NumObjs++;

                //Initialise the GCHeader
                SetSignature(newObjPtr);
                newObjPtr->RefCount = 1;
                //Initialise the object _Type field
                FOS_System.ObjectWithType newObj = (FOS_System.ObjectWithType)Utilities.ObjectUtilities.GetObject(newObjPtr + 1);
                newObj._Type = theType;

                //Move past GCHeader
                byte* newObjBytePtr = (byte*)(newObjPtr + 1);

                InsideGC = false;

                return newObjBytePtr;
            }
            finally
            {
                ExitCritical();
            }
        }