#if DEBUG //#define GC_DEBUG #endif using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; namespace Indy.IL2CPU { public static class GCImplementation { private static int mLock = 0; private static void AcquireLock() { do { } while (Interlocked.CompareExchange(ref mLock, 1, 0) != 0); } private static void ReleaseLock() { do { } while (Interlocked.CompareExchange(ref mLock, 0, 1) != 1); } public static uint AllocNewObject(uint aSize) { uint xNewObject = RuntimeEngine.Heap_AllocNewObject(aSize + 4); #if GC_DEBUG Console.Write("New Object allocated: "); WriteNumber(xNewObject + 4, false); Console.WriteLine(); #endif return xNewObject + 4; } /// /// This function gets the pointer to the memory location of where it's stored. /// /// public static unsafe void IncRefCount(uint aObject) { // if (aObject == 0) { // return; // } // uint* xTheObject = (uint*)aObject; // xTheObject += 1; // if ((*xTheObject & 0x80000000) != 0) { // return; // } // xTheObject -= 2; // if ((*xTheObject & 0x88888888) != 0) { // Console.Write("StaleObject: "); // WriteNumber(aObject, false); // Console.WriteLine(); // return; // } //xTheObject -= 2; #if GC_DEBUG uint xCount = #endif // *xTheObject = *xTheObject + 1; #if GC_DEBUG if (xCount == 0x80000000) { Console.WriteLine("GC: RefCount Maximum Exceeded!"); return; } Console.Write("ObjectIncRefCount, Object = "); WriteNumber(aObject, false); Console.Write(", RefCount = "); WriteNumber(xCount, false); Console.WriteLine(); #endif } /// /// This function gets the pointer to the memory location of where it's stored. /// /// public static unsafe void DecRefCount(uint aObject) { // if (aObject == 0) { // return; // } // uint* xTheObject = (uint*)aObject; // xTheObject += 1; // check for staticly embedded arrays/objects. these are embedded as values in the binary target, and should // therefore not be collected. // if ((*xTheObject & 0x80000000) == 0x80000000) { // return; // } // xTheObject -= 2; // uint xCount = *xTheObject; // if (xCount == 0) { // return; // } #if GC_DEBUG if ((xCount & 0x80000000) == 0x80000000) { Console.Write("StaleObject: "); WriteNumber(aObject, false); Console.WriteLine(); return; } #endif // xCount = *xTheObject = xCount - 1; // if (xCount == 0) { #if GC_DEBUG Console.Write("ObjectReclaimed, Object = "); WriteNumber(aObject, false); Console.WriteLine(); xTheObject = (uint*)(aObject - 4); *xTheObject = 0x80000000; xTheObject = (uint*)(aObject + 4); // uint xObjectType = *xTheObject; // if (xObjectType == 1) { // xTheObject = (uint*)aObject + 8; // uint xFieldCount = *xTheObject; // for (uint i = 0; i < xFieldCount; i++) { // xTheObject += 4; // DecRefCount(*xTheObject); // } // } #endif #if !GC_DEBUG // RuntimeEngine.Heap_Free(aObject - 4); #endif #if GC_DEBUG } else { Console.Write("ObjectDecRefCount, Object = "); WriteNumber(aObject, false); Console.Write(", RefCount = "); WriteNumber(xCount, false); Console.WriteLine(); #endif // } } #if GC_DEBUG private static void WriteNumber(uint aValue, bool aZeroFill) { uint xValue = aValue; byte xCurrentBits = 32; byte xCharsWritten = 0; bool xSignificantDigitWritten = aZeroFill; Console.Write("0x"); while (xCurrentBits >= 4) { xCurrentBits -= 4; byte xCurrentDigit = (byte)((xValue >> xCurrentBits) & 0xF); string xDigitString = null; switch (xCurrentDigit) { case 0: if (xSignificantDigitWritten) { xDigitString = "0"; goto default; } break; case 1: xDigitString = "1"; goto default; case 2: xDigitString = "2"; goto default; case 3: xDigitString = "3"; goto default; case 4: xDigitString = "4"; goto default; case 5: xDigitString = "5"; goto default; case 6: xDigitString = "6"; goto default; case 7: xDigitString = "7"; goto default; case 8: xDigitString = "8"; goto default; case 9: xDigitString = "9"; goto default; case 10: xDigitString = "A"; goto default; case 11: xDigitString = "B"; goto default; case 12: xDigitString = "C"; goto default; case 13: xDigitString = "D"; goto default; case 14: xDigitString = "E"; goto default; case 15: xDigitString = "F"; goto default; default: if (xDigitString == null) { Console.Write("NoDigitSet"); } xSignificantDigitWritten = true; xCharsWritten += 1; Console.Write(xDigitString); break; } } } #endif } }