1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-23 18:18:00 +02:00

Extensive runtime refactor to reduce generated executable sizes

This commit is contained in:
Brian Fiete 2024-03-16 07:23:29 -04:00
parent 4e750a7e1a
commit ddd9b1b218
74 changed files with 2514 additions and 717 deletions

View file

@ -24,7 +24,7 @@ OtherLinkFlags = ""
TargetDirectory = "$(WorkspaceDir)/dist"
TargetName = "BeefIDE_d"
OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib"
DebugCommandArguments = "-proddir=\"$(WorkspaceDir)\\..\\IDE\""
DebugCommandArguments = "-proddir=\"$(WorkspaceDir)\\..\\BeefBuild\""
DebugWorkingDirectory = "$(WorkspaceDir)\\.."
EnvironmentVars = ["_NO_DEBUG_HEAP=1"]

View file

@ -0,0 +1,8 @@
FileVersion = 1
[Project]
Name = "Tiny"
StartupObject = "Tiny.Program"
[Configs.Release.Win64]
CLibType = "SystemMSVCRT"

View file

@ -0,0 +1,26 @@
FileVersion = 1
Projects = {Tiny = {Path = "."}}
Unlocked = ["corlib"]
[Workspace]
StartupProject = "Tiny"
[Configs.Debug.Win64]
AllocType = "CRT"
RuntimeKind = "Reduced"
ReflectKind = "Minimal"
RuntimeChecks = false
EmitDynamicCastCheck = false
EnableObjectDebugFlags = false
EmitObjectAccessCheck = false
EnableRealtimeLeakCheck = false
AllowHotSwapping = false
IntermediateType = "ObjectAndIRCode"
[Configs.Debug.Win32]
RuntimeKind = "Reduced"
ReflectKind = "Minimal"
[Configs.Release.Win64]
RuntimeKind = "Reduced"
ReflectKind = "Minimal"

View file

@ -0,0 +1,13 @@
using System;
using System.Diagnostics;
namespace Tiny;
class Program
{
public static int Main()
{
Console.WriteLine("Hello, World!");
return 0;
}
}

View file

@ -110,13 +110,13 @@ namespace System
[AttributeUsage(.Method | .Constructor | .Invocation)]
public struct InlineAttribute : Attribute
{
}
[AttributeUsage(.Invocation)]
public struct UnboundAttribute : Attribute
{
}
[AttributeUsage(.Class | .Struct | .Interface | .Method | .Constructor)]
@ -136,13 +136,13 @@ namespace System
[AttributeUsage(.MemberAccess | .Alloc)]
public struct FriendAttribute : Attribute
{
}
[AttributeUsage(.MemberAccess)]
public struct NoExtensionAttribute : Attribute
{
}
[AttributeUsage(.Block)]
@ -161,13 +161,13 @@ namespace System
[AttributeUsage(.Method | .Class | .Struct | .Enum)]
public struct OptimizeAttribute : Attribute
{
}
[AttributeUsage(.Method | .Class | .Struct | .Enum)]
public struct UseLLVMAttribute : Attribute
{
}
[AttributeUsage(.Method /*2*/ | .StaticField)]
@ -344,7 +344,7 @@ namespace System
[AttributeUsage(.Enum)]
public struct AllowDuplicatesAttribute : Attribute
{
}
[AttributeUsage(.Class | .Struct)]
@ -409,7 +409,7 @@ namespace System
public struct ExportAttribute : Attribute
{
}
[AttributeUsage(.StaticField | .Field, .NotInherited)]
@ -420,6 +420,12 @@ namespace System
}
}
[AttributeUsage(.MemberAccess)]
public struct NoStaticCtorAttribute : Attribute
{
}
/// The [Checked] attribute is used to mark a method or a method invocation as being "checked", meaning
/// that the method applies extra runtime checks such as bounds checking or other parameter or state validation.
[AttributeUsage(.Invocation | .Method | .Property)]

View file

@ -92,8 +92,15 @@ namespace System
[CallingConvention(.Cdecl)]
public static extern void Dbg_RawFree(void* ptr);
[CallingConvention(.Cdecl)]
static extern void Shutdown_Internal();
[CallingConvention(.Cdecl), AlwaysInclude]
static extern void Shutdown();
static void Shutdown()
{
Shutdown_Internal();
}
[CallingConvention(.Cdecl)]
static extern void Test_Init(char8* testData);
[CallingConvention(.Cdecl)]

View file

@ -48,63 +48,122 @@ namespace System
class Object : IHashable
{
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
int mClassVData;
int mDbgAllocInfo;
#else
ClassVData* mClassVData;
#endif
public virtual ~this()
{
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
int mClassVData;
int mDbgAllocInfo;
#else
ClassVData* mClassVData;
#endif
public virtual ~this()
{
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
mClassVData = ((mClassVData & ~0x08) | 0x80);
#endif
}
#endif
}
int IHashable.GetHashCode()
{
return (int)(void*)this;
}
public Type GetType()
{
Type type;
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
type = maskedVData.mType;
#else
type = mClassVData.mType;
#endif
if ((type.[Friend]mTypeFlags & TypeFlags.Boxed) != 0)
{
//int32 underlyingType = (int32)((TypeInstance)type).mUnderlyingType;
type = Type.[Friend]GetType(((TypeInstance)type).[Friend]mUnderlyingType);
}
[NoShow]
int32 GetFlags()
{
return (int32)mClassVData & 0xFF;
}
[DisableObjectAccessChecks, NoShow]
public bool IsDeleted()
{
return (int32)mClassVData & 0x80 != 0;
}
#else
[SkipCall]
public bool IsDeleted()
{
return false;
}
#endif
extern Type Comptime_GetType();
public Type GetType()
{
if (Compiler.IsComptime)
return Comptime_GetType();
ClassVData* classVData;
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
#else
classVData = mClassVData;
#endif
#if BF_32_BIT
Type type = Type.[Friend]GetType_((.)(classVData.mType2));
#else
Type type = Type.[Friend]GetType_((.)(classVData.mType >> 32));
#endif
return type;
}
TypeId GetTypeId()
{
ClassVData* classVData;
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
#else
classVData = mClassVData;
#endif
#if BF_32_BIT
return (.)classVData.mType2;
#else
return (.)(classVData.mType >> 32);
#endif
}
[NoShow]
Type RawGetType()
{
Type type;
if (Compiler.IsComptime)
return Comptime_GetType();
ClassVData* classVData;
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
type = maskedVData.mType;
#else
type = mClassVData.mType;
#endif
return type;
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
#else
classVData = mClassVData;
#endif
#if BF_32_BIT
Type type = Type.[Friend]GetType_((.)(classVData.mType));
#else
Type type = Type.[Friend]GetType_((.)(classVData.mType & 0xFFFFFFFF));
#endif
return type;
}
TypeId RawGetTypeId()
{
ClassVData* classVData;
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
classVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
#else
classVData = mClassVData;
#endif
#if BF_32_BIT
return (.)classVData.mType;
#else
return (.)(classVData.mType & 0xFFFFFFFF);
#endif
}
#if BF_DYNAMIC_CAST_CHECK || BF_ENABLE_REALTIME_LEAK_CHECK
[NoShow]
public virtual Object DynamicCastToTypeId(int32 typeId)
{
if (typeId == (int32)RawGetType().[Friend]mTypeId)
return this;
return null;
}
public virtual Object DynamicCastToTypeId(int32 typeId)
{
if (typeId == (.)RawGetTypeId())
return this;
return null;
}
[NoShow]
public virtual Object DynamicCastToInterface(int32 typeId)
@ -112,13 +171,18 @@ namespace System
return null;
}
#endif
int IHashable.GetHashCode()
{
return (int)Internal.UnsafeCastToPtr(this);
}
public virtual void ToString(String strBuffer)
{
//strBuffer.Set(stack string(GetType().mName));
RawGetType().GetName(strBuffer);
strBuffer.Append("Type#");
GetTypeId().ToString(strBuffer);
}
/*public virtual int GetHashCode()
{
return (int)(intptr)(void*)this;
@ -138,12 +202,12 @@ namespace System
obj.ToString(strBuffer);
}
}
interface IResult<T>
{
T GetBaseResult();
}
struct ValueType
{
public static extern bool Equals<T>(T val1, T val2);
@ -197,7 +261,7 @@ namespace System
{
return CSize;
}
}
}
public explicit static operator T[CSize] (Self val)
{
@ -226,11 +290,11 @@ namespace System
struct Void : void
{
}
struct Boolean : bool
{
{
}
struct Char8 : char8
{
public bool IsWhiteSpace
@ -248,7 +312,7 @@ namespace System
struct Char16 : char16
{
}
struct Char32 : char32
@ -258,15 +322,15 @@ namespace System
get;
}
}
struct Int8 : int8
{
{
}
struct UInt8 : uint8
{
{
}
struct Int16 : int16, IOpComparable, IIsNaN
{
public static int operator<=>(Int16 a, Int16 b)
@ -283,11 +347,11 @@ namespace System
}
}
}
struct UInt16 : uint16
{
{
}
struct UInt32 : uint32, IHashable, IOpComparable, IIsNaN, IOpNegatable
{
public const int32 MaxValue = 0x7FFFFFFF;
@ -307,7 +371,7 @@ namespace System
public this()
{
}
bool IIsNaN.IsNaN
@ -324,12 +388,12 @@ namespace System
return (.)this;
}
}
struct Int64 : int64
{
public const int64 MaxValue = 0x7FFFFFFFFFFFFFFFL;
public const int64 MinValue = -0x8000000000000000L;
public override void ToString(String strBuffer)
{
// Dumb, make better.
@ -344,11 +408,11 @@ namespace System
}
if (charIdx == 14)
strChars[charIdx--] = '0';
char8* charPtr = &strChars[charIdx + 1];
char8* charPtr = &strChars[charIdx + 1];
strBuffer.Append(scope:: String(charPtr));
}
}
struct UInt64 : uint64
{
}
@ -405,7 +469,7 @@ namespace System
}
struct UInt : uint, IOpComparable, IIsNaN
{
{
public static int operator<=>(UInt a, UInt b)
{
return (uint)a <=> (uint)b;
@ -469,11 +533,11 @@ namespace System
}
if (charIdx == 14)
strChars[charIdx--] = '0';
char8* charPtr = &strChars[charIdx + 1];
char8* charPtr = &strChars[charIdx + 1];
strBuffer.Append(scope:: String(charPtr));
}
}
struct Enum
{
public static Result<T> Parse<T>(String str) where T : Enum
@ -528,7 +592,7 @@ namespace System
{
public int64 mMethodId;
public DeferredCall* mNext;
public void Cancel() mut
{
mMethodId = 0;

View file

@ -7,7 +7,10 @@ namespace System
{
struct ClassVData
{
public Type mType;
public int mType;
#if BF_32_BIT
public int mType2;
#endif
// The rest of this structured is generated by the compiler,
// including the vtable and interface slots
}
@ -757,6 +760,7 @@ namespace System.Reflection
public int32 mCustomAttributesIdx;
}
[CRepr, AlwaysInclude]
public struct InterfaceData
{
public TypeId mInterfaceType;

View file

@ -46,8 +46,8 @@ namespace Hey.Dude.Bro
[Import(@"C:\Beef\BeefTools\TestDLL\x64\Debug\TestDLL.dll"), LinkName("Test2")]
public static extern void Test2(int32 a, int32 b, int32 c, int32 d, function Color(int32 a, int32 b) func);
//[Import(@"C:\Beef\BeefTools\TestDLL\x64\Debug\TestDLL.dll"), LinkName("Test2")]
//public static extern void Test2(int32 a, int32 b, int32 c, int32 d, function Color(int32 a, int32 b) func);
public static Color GetColor(int32 a, int32 b)
{
@ -61,7 +61,9 @@ namespace Hey.Dude.Bro
public static int Main(String[] args)
{
Test2(1, 2, 3, 4, => GetColor);
Debug.WriteLine("Hey!");
//Test2(1, 2, 3, 4, => GetColor);
//Blurg.Hey();
return 1;

View file

@ -763,7 +763,10 @@ namespace IDE
}
public static void GetRtLibNames(Workspace.PlatformType platformType, Workspace.Options workspaceOptions, Project.Options options, bool dynName, String outRt, String outDbg, String outAlloc)
{
{
if (workspaceOptions.mRuntimeKind == .Disabled)
return;
if ((platformType == .Linux) || (platformType == .macOS) || (platformType == .iOS))
{
if (options.mBuildOptions.mBeefLibType == .DynamicDebug)
@ -1059,10 +1062,13 @@ namespace IDE
return false;
}*/
switch (options.mBuildOptions.mCLibType)
var clibType = options.mBuildOptions.mCLibType;
if (workspaceOptions.mRuntimeKind == .Disabled)
clibType = .None;
switch (clibType)
{
case .None:
linkLine.Append("-nodefaultlib ");
linkLine.Append("-nodefaultlib chkstk.obj ");
case .Dynamic:
//linkLine.Append((workspaceOptions.mMachineType == .x86) ? "-defaultlib:msvcprt " : "-defaultlib:msvcrt ");
linkLine.Append("-defaultlib:msvcrt ");

View file

@ -5,6 +5,7 @@ namespace IDE
{
class BuildOptions
{
[Reflect(.All)]
public enum LTOType
{
case None;
@ -18,6 +19,7 @@ namespace IDE
}
}
[Reflect(.All)]
public enum EmitDebugInfo
{
No,
@ -25,6 +27,7 @@ namespace IDE
LinesOnly,
}
[Reflect(.All)]
public enum SIMDSetting
{
None,
@ -38,6 +41,7 @@ namespace IDE
AVX2,
}
[Reflect]
public enum BfOptimizationLevel
{
case O0;
@ -53,6 +57,7 @@ namespace IDE
}
}
[Reflect]
public enum RelocType
{
NotSet,
@ -64,6 +69,7 @@ namespace IDE
ROPI_RWPI
}
[Reflect]
public enum PICLevel
{
NotSet,
@ -72,6 +78,7 @@ namespace IDE
Big
}
[Reflect]
public enum AlwaysIncludeKind
{
NotSet,

View file

@ -739,9 +739,14 @@ namespace IDE.Compiler
SetOpt(options.mAllowHotSwapping, .EnableHotSwapping);
#endif
var allocType = options.mAllocType;
if ((options.mRuntimeKind == .Disabled) && (allocType == .Debug))
allocType = .CRT;
String mallocLinkName;
String freeLinkName;
switch (options.mAllocType)
switch (allocType)
{
case .CRT:
mallocLinkName = "malloc";

View file

@ -366,6 +366,9 @@ namespace IDE.Debugger
[CallingConvention(.Stdcall),CLink]
static extern char8* Debugger_GetModulesInfo();
[CallingConvention(.Stdcall),CLink]
static extern char8* Debugger_GetModuleInfo(char8* moduleName);
[CallingConvention(.Stdcall),CLink]
static extern bool Debugger_HasPendingDebugLoads();
@ -1194,6 +1197,11 @@ namespace IDE.Debugger
modulesInfo.Append(Debugger_GetModulesInfo());
}
public void GetModuleInfo(StringView moduleName, String moduleInfo)
{
moduleInfo.Append(Debugger_GetModuleInfo(moduleName.ToScopeCStr!()));
}
public int32 LoadDebugInfoForModule(String moduleName)
{
return Debugger_LoadDebugInfoForModule(moduleName);

View file

@ -8488,6 +8488,13 @@ namespace IDE
macroList.Add("BF_LARGE_COLLECTIONS");
}
if (workspaceOptions.mRuntimeKind == .Disabled)
macroList.Add("BF_RUNTIME_DISABLE");
if ((workspaceOptions.mRuntimeKind == .Reduced) || (workspaceOptions.mRuntimeKind == .Disabled))
macroList.Add("BF_RUNTIME_REDUCED");
if (workspaceOptions.mReflectKind == .Minimal)
macroList.Add("BF_REFLECT_MINIMAL");
// Only supported on Windows at the moment
bool hasLeakCheck = false;
if (workspaceOptions.LeakCheckingEnabled)

View file

@ -94,6 +94,12 @@ namespace IDE
BitcodeAndIRCode,
}
public enum ReflectKind
{
Normal,
Minimal
}
public enum PlatformType
{
case Unknown;
@ -263,6 +269,13 @@ namespace IDE
Custom
}
public enum RuntimeKind
{
Default,
Reduced,
Disabled
}
public class BeefGlobalOptions
{
[Reflect]
@ -305,6 +318,10 @@ namespace IDE
[Reflect]
public bool mLargeCollections;
[Reflect]
public RuntimeKind mRuntimeKind;
[Reflect]
public ReflectKind mReflectKind;
[Reflect]
public AllocType mAllocType = .CRT;
[Reflect]
public String mAllocMalloc = new String() ~ delete _;
@ -352,7 +369,7 @@ namespace IDE
get
{
#if BF_PLATFORM_WINDOWS
return mEnableRealtimeLeakCheck && mEnableObjectDebugFlags && (mAllocType == .Debug);
return mEnableRealtimeLeakCheck && mEnableObjectDebugFlags && (mAllocType == .Debug) && (mRuntimeKind != .Disabled);
#else
return false;
#endif
@ -376,6 +393,8 @@ namespace IDE
mNoOmitFramePointers = prev.mNoOmitFramePointers;
mLargeStrings = prev.mLargeStrings;
mLargeCollections = prev.mLargeCollections;
mRuntimeKind = prev.mRuntimeKind;
mReflectKind = prev.mReflectKind;
mAllocType = prev.mAllocType;
mAllocMalloc.Set(prev.mAllocMalloc);
mAllocFree.Set(prev.mAllocFree);
@ -813,6 +832,8 @@ namespace IDE
data.ConditionalAdd("NoOmitFramePointers", options.mNoOmitFramePointers, false);
data.ConditionalAdd("LargeStrings", options.mLargeStrings, false);
data.ConditionalAdd("LargeCollections", options.mLargeCollections, false);
data.ConditionalAdd("RuntimeKind", options.mRuntimeKind);
data.ConditionalAdd("ReflectKind", options.mReflectKind);
data.ConditionalAdd("InitLocalVariables", options.mInitLocalVariables, false);
data.ConditionalAdd("RuntimeChecks", options.mRuntimeChecks, !isRelease);
data.ConditionalAdd("EmitDynamicCastCheck", options.mEmitDynamicCastCheck, !isRelease);
@ -1004,6 +1025,8 @@ namespace IDE
options.mNoOmitFramePointers = false;
options.mLargeStrings = false;
options.mLargeCollections = false;
options.mRuntimeKind = .Default;
options.mReflectKind = .Normal;
options.mInitLocalVariables = false;
options.mRuntimeChecks = !isRelease;
options.mEmitDynamicCastCheck = !isRelease;
@ -1113,6 +1136,8 @@ namespace IDE
options.mNoOmitFramePointers = data.GetBool("NoOmitFramePointers", false);
options.mLargeStrings = data.GetBool("LargeStrings", false);
options.mLargeCollections = data.GetBool("LargeCollections", false);
options.mRuntimeKind = data.GetEnum<RuntimeKind>("RuntimeKind");
options.mReflectKind = data.GetEnum<ReflectKind>("ReflectKind");
options.mInitLocalVariables = data.GetBool("InitLocalVariables", false);
options.mRuntimeChecks = data.GetBool("RuntimeChecks", !isRelease);
options.mEmitDynamicCastCheck = data.GetBool("EmitDynamicCastCheck", !isRelease);

View file

@ -158,6 +158,20 @@ namespace IDE.ui
}
});
});
anItem = menu.AddItem("Copy Info to Clipboard");
anItem.mOnMenuItemSelected.Add(new (item) =>
{
String moduleInfo = scope .();
listView.GetRoot().WithSelectedItems(scope (item) =>
{
if (!moduleInfo.IsEmpty)
moduleInfo.Append("\n");
gApp.mDebugger.GetModuleInfo(item.GetSubItem(1).Label, moduleInfo);
});
gApp.SetClipboardText(moduleInfo);
});
MenuWidget menuWidget = ThemeFactory.mDefault.CreateMenuWidget(menu);
menuWidget.Init(relWidget, x, y);
}

View file

@ -797,6 +797,8 @@ namespace IDE.ui
AddPropertiesItem(category, "No Omit Frame Pointers", "mNoOmitFramePointers");
AddPropertiesItem(category, "Large Strings", "mLargeStrings");
AddPropertiesItem(category, "Large Collections", "mLargeCollections");
AddPropertiesItem(category, "Runtime", "mRuntimeKind");
AddPropertiesItem(category, "Reflection", "mReflectKind");
category.Open(true, true);
(category, propEntry) = AddPropertiesItem(root, "Debug");