Brian Fiete 2 ماه پیش
والد
کامیت
c889877443
3فایلهای تغییر یافته به همراه220 افزوده شده و 5 حذف شده
  1. 213 4
      IDE/mintest/minlib/src/System/Internal.bf
  2. 6 0
      IDE/mintest/minlib/src/System/Object.bf
  3. 1 1
      IDE/mintest/minlib/src/System/Type.bf

+ 213 - 4
IDE/mintest/minlib/src/System/Internal.bf

@@ -13,6 +13,33 @@ namespace System
 	[AlwaysInclude]
     static class Internal
     {
+		enum BfObjectFlags : uint8
+		{
+			None			= 0,
+			Mark1			= 0x01,
+			Mark2			= 0x02,
+			Mark3			= 0x03,
+			Allocated		= 0x04,
+			StackAlloc		= 0x08,
+			AppendAlloc		= 0x10,
+			AllocInfo		= 0x20,
+			AllocInfo_Short = 0x40,	
+			Deleted			= 0x80
+		};
+
+		struct AppendAllocEntry
+		{
+			public enum Kind
+			{
+				case None;
+				case Object(Object obj);
+				case Raw(void* ptr, DbgRawAllocData* allocData);
+			}
+
+			public Kind mKind;
+			public AppendAllocEntry* mNext;
+		}
+
 		[Intrinsic("cast")]
         public static extern Object UnsafeCastToObject(void* ptr);
 		[Intrinsic("cast")]
@@ -64,19 +91,19 @@ namespace System
 		[CallingConvention(.Cdecl)]
 		public static extern void Dbg_ObjectCreated(Object obj, int size, ClassVData* classVData);
 		[CallingConvention(.Cdecl)]
-		public static extern void Dbg_ObjectCreatedEx(Object obj, int size, ClassVData* classVData);
+		public static extern void Dbg_ObjectCreatedEx(Object obj, int size, ClassVData* classVData, uint8 allocFlags);
 		[CallingConvention(.Cdecl)]
 		public static extern void Dbg_ObjectAllocated(Object obj, int size, ClassVData* classVData);
 		[CallingConvention(.Cdecl)]
-		public static extern void Dbg_ObjectAllocatedEx(Object obj, int size, ClassVData* classVData);
+		public static extern void Dbg_ObjectAllocatedEx(Object obj, int size, ClassVData* classVData, uint8 allocFlags);
 		[CallingConvention(.Cdecl)]
 		public static extern int Dbg_PrepareStackTrace(int baseAllocSize, int maxStackTraceDepth);
 		[CallingConvention(.Cdecl)]
-		public static extern void Dbg_ObjectStackInit(Object object, ClassVData* classVData);
+		public static extern void Dbg_ObjectStackInit(Object object, ClassVData* classVData, int size, uint8 allocFlags);
 		[CallingConvention(.Cdecl)]
 		public static extern Object Dbg_ObjectAlloc(TypeInstance typeInst, int size);
 		[CallingConvention(.Cdecl)]
-		public static extern Object Dbg_ObjectAlloc(ClassVData* classVData, int size, int align, int maxStackTraceDepth);
+		public static extern Object Dbg_ObjectAlloc(ClassVData* classVData, int size, int align, int maxStackTraceDepth, uint8 flags);
 		[CallingConvention(.Cdecl)]
 		public static extern void Dbg_ObjectPreDelete(Object obj);
 		[CallingConvention(.Cdecl)]
@@ -92,6 +119,188 @@ namespace System
 		[CallingConvention(.Cdecl)]
 		public static extern void Dbg_RawFree(void* ptr);
 
+		#if BF_ENABLE_OBJECT_DEBUG_FLAGS
+		static void AddAppendInfo(Object rootObj, AppendAllocEntry.Kind kind)
+		{
+			Compiler.Assert(sizeof(AppendAllocEntry) <= sizeof(int)*4);
+
+			void Handle(AppendAllocEntry* headAllocEntry)
+			{
+				if (headAllocEntry.mKind case .None)
+				{
+					headAllocEntry.mKind = kind;
+				}
+				else
+				{
+					AppendAllocEntry* newAppendAllocEntry = (.)new uint8[sizeof(AppendAllocEntry)]*;
+					newAppendAllocEntry.mKind = kind;
+					newAppendAllocEntry.mNext = headAllocEntry.mNext;
+					headAllocEntry.mNext = newAppendAllocEntry;
+				}
+			}
+
+			if (rootObj.[Friend]mClassVData & (int)BfObjectFlags.AllocInfo_Short != 0)
+			{
+				var dbgAllocInfo = rootObj.[DisableObjectAccessChecks, Friend]mDbgAllocInfo;
+				uint8 allocFlag = (.)(dbgAllocInfo >> 8);
+				//Debug.Assert(allocFlag == 1);
+				if ((allocFlag & 1) != 0)
+				{
+					int allocSize = (.)(dbgAllocInfo >> 16);
+					int capturedTraceCount = (uint8)(dbgAllocInfo);
+					uint8* ptr = (.)Internal.UnsafeCastToPtr(rootObj);
+					ptr += allocSize + capturedTraceCount * sizeof(int);
+					Handle((.)ptr);
+				}
+			}
+			else if (rootObj.[Friend]mClassVData & (int)BfObjectFlags.AllocInfo != 0)
+			{
+				var dbgAllocInfo = rootObj.[DisableObjectAccessChecks, Friend]mDbgAllocInfo;
+				int allocSize = dbgAllocInfo;
+				uint8* ptr = (.)Internal.UnsafeCastToPtr(rootObj);
+				int info = *(int*)(ptr + allocSize);
+				int capturedTraceCount = info >> 8;
+				uint8 allocFlag = (.)info;
+				//Debug.Assert(allocFlag == 1);
+				if ((allocFlag & 1) != 0)
+				{
+					ptr += allocSize + capturedTraceCount * sizeof(int) + sizeof(int);
+					Handle((.)ptr);
+				}
+			}
+		}
+#endif
+
+		public static void Dbg_ObjectAppended(Object rootObj, Object appendObj)
+		{
+#if BF_ENABLE_OBJECT_DEBUG_FLAGS
+			AddAppendInfo(rootObj, .Object(appendObj));
+#endif
+		}
+
+		public static void Dbg_RawAppended(Object rootObj, void* ptr, DbgRawAllocData* rawAllocData)
+		{
+#if BF_ENABLE_OBJECT_DEBUG_FLAGS
+			AddAppendInfo(rootObj, .Raw(ptr, rawAllocData));
+#endif
+		}
+
+		public static void Dbg_MarkAppended(Object rootObj)
+		{
+#if BF_ENABLE_OBJECT_DEBUG_FLAGS
+			void Handle(AppendAllocEntry* checkAllocEntry)
+			{
+				var checkAllocEntry;
+				while (checkAllocEntry != null)
+				{
+					switch (checkAllocEntry.mKind)
+					{
+					case .Object(let obj):
+						obj.[Friend]GCMarkMembers();
+					case .Raw(let rawPtr, let allocData):
+						((function void(void*))allocData.mMarkFunc)(rawPtr);
+					default:
+					}
+
+					checkAllocEntry = checkAllocEntry.mNext;
+				}
+			}
+
+			if (rootObj.[DisableObjectAccessChecks, Friend]mClassVData & (int)BfObjectFlags.AllocInfo_Short != 0)
+			{
+				var dbgAllocInfo = rootObj.[DisableObjectAccessChecks, Friend]mDbgAllocInfo;
+				uint8 allocFlag = (.)(dbgAllocInfo >> 8);
+				if ((allocFlag & 1) != 0)
+				{
+					int allocSize = (.)(dbgAllocInfo >> 16);
+					int capturedTraceCount = (uint8)(dbgAllocInfo);
+					uint8* ptr = (.)Internal.UnsafeCastToPtr(rootObj);
+					ptr += allocSize + capturedTraceCount * sizeof(int);
+					Handle((.)ptr);
+				}
+			}
+			else if (rootObj.[DisableObjectAccessChecks, Friend]mClassVData & (int)BfObjectFlags.AllocInfo != 0)
+			{
+				var dbgAllocInfo = rootObj.[DisableObjectAccessChecks, Friend]mDbgAllocInfo;
+				int allocSize = dbgAllocInfo;
+				uint8* ptr = (.)Internal.UnsafeCastToPtr(rootObj);
+				int info = *(int*)(ptr + allocSize);
+				int capturedTraceCount = info >> 8;
+				uint8 allocFlag = (.)info;
+				if ((allocFlag & 1) != 0)
+				{
+					ptr += allocSize + capturedTraceCount * sizeof(int) + sizeof(int);
+					Handle((.)ptr);
+				}
+			}
+#endif
+		}
+
+		public static void Dbg_AppendDeleted(Object rootObj, bool doChecks)
+		{
+#if BF_ENABLE_OBJECT_DEBUG_FLAGS
+			void Handle(AppendAllocEntry* headAllocEntry)
+			{
+				AppendAllocEntry* checkAllocEntry = headAllocEntry;
+				while (checkAllocEntry != null)
+				{
+					switch (checkAllocEntry.mKind)
+					{
+					case .Object(let obj):
+						if (doChecks)
+						{
+#unwarn
+							if (!obj.[DisableObjectAccessChecks]IsDeleted())
+							{
+								if (obj.GetType().HasDestructor)
+								{
+									Runtime.FatalError("Appended object not deleted with 'delete:append'");
+								}
+							}
+						}
+					case .Raw(let rawPtr, let allocData):
+					default:
+					}
+
+					var nextAllocEntry = checkAllocEntry.mNext;
+					if (checkAllocEntry == headAllocEntry)
+						*checkAllocEntry = default;
+					else
+						delete (uint8*)checkAllocEntry;
+					checkAllocEntry = nextAllocEntry;
+				}
+			}
+
+			if (rootObj.[DisableObjectAccessChecks, Friend]mClassVData & (int)BfObjectFlags.AllocInfo_Short != 0)
+			{
+				var dbgAllocInfo = rootObj.[DisableObjectAccessChecks, Friend]mDbgAllocInfo;
+				uint8 allocFlag = (.)(dbgAllocInfo >> 8);
+				if ((allocFlag & 1) != 0)
+				{
+					int allocSize = (.)(dbgAllocInfo >> 16);
+					int capturedTraceCount = (uint8)(dbgAllocInfo);
+					uint8* ptr = (.)Internal.UnsafeCastToPtr(rootObj);
+					ptr += allocSize + capturedTraceCount * sizeof(int);
+					Handle((.)ptr);
+				}
+			}
+			else if (rootObj.[DisableObjectAccessChecks, Friend]mClassVData & (int)BfObjectFlags.AllocInfo != 0)
+			{
+				var dbgAllocInfo = rootObj.[DisableObjectAccessChecks, Friend]mDbgAllocInfo;
+				int allocSize = dbgAllocInfo;
+				uint8* ptr = (.)Internal.UnsafeCastToPtr(rootObj);
+				int info = *(int*)(ptr + allocSize);
+				int capturedTraceCount = info >> 8;
+				uint8 allocFlag = (.)info;
+				if ((allocFlag & 1) != 0)
+				{
+					ptr += allocSize + capturedTraceCount * sizeof(int) + sizeof(int);
+					Handle((.)ptr);
+				}
+			}
+#endif
+		}
+
 		[CallingConvention(.Cdecl)]
 		static extern void Shutdown_Internal();
 

+ 6 - 0
IDE/mintest/minlib/src/System/Object.bf

@@ -172,6 +172,12 @@ namespace System
 		}
 #endif
 
+		[NoShow]
+		public virtual Object DynamicCastToSignature(int32 sig)
+		{
+		    return null;
+		}
+
 		int IHashable.GetHashCode()
 		{
 		    return (int)Internal.UnsafeCastToPtr(this);

+ 1 - 1
IDE/mintest/minlib/src/System/Type.bf

@@ -1266,7 +1266,7 @@ namespace System.Reflection
 			int32 stackCount = Compiler.Options.AllocStackCount;
 			if (mAllocStackCountOverride != 0)
 				stackCount = mAllocStackCountOverride;
-			obj = Internal.Dbg_ObjectAlloc([Friend]mTypeClassVData, arraySize, [Friend]mInstAlign, stackCount);
+			obj = Internal.Dbg_ObjectAlloc([Friend]mTypeClassVData, arraySize, [Friend]mInstAlign, stackCount, 0);
 #else
 			void* mem = new [Align(16)] uint8[arraySize]* (?);
 			obj = Internal.UnsafeCastToObject(mem);