Cosmos/source/Indy.IL2CPU/GCImplementation.cs
2007-11-23 18:33:19 +00:00

209 lines
No EOL
5.2 KiB
C#

#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;
}
/// <summary>
/// This function gets the pointer to the memory location of where it's stored.
/// </summary>
/// <param name="aObject"></param>
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
}
/// <summary>
/// This function gets the pointer to the memory location of where it's stored.
/// </summary>
/// <param name="aObject"></param>
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
}
}