diff --git a/IDE/src/Commands.bf b/IDE/src/Commands.bf index 71b6204f..a3f26f1a 100644 --- a/IDE/src/Commands.bf +++ b/IDE/src/Commands.bf @@ -254,6 +254,7 @@ namespace IDE Add("Show Call Stack", new => gApp.ShowCallstack); Add("Show Class View", new => gApp.ShowClassViewPanel); Add("Show Current", new => gApp.Cmd_ShowCurrent); + Add("Show Diagnostics", new => gApp.ShowDiagnostics); Add("Show Disassembly", new => gApp.[Friend]ShowDisassemblyAtStack); Add("Show Errors", new => gApp.[Friend]ShowErrors); Add("Show Error Next", new => gApp.ShowErrorNext); diff --git a/IDE/src/Debugger/DebugManager.bf b/IDE/src/Debugger/DebugManager.bf index 72cad845..529b4274 100644 --- a/IDE/src/Debugger/DebugManager.bf +++ b/IDE/src/Debugger/DebugManager.bf @@ -273,6 +273,9 @@ namespace IDE.Debugger [CallingConvention(.Stdcall),CLink] static extern char8* CallStack_GetStackMethodOwner(int32 stackFrameIdx, out int32 language); + [CallingConvention(.Stdcall),CLink] + static extern char8* Debugger_GetProcessInfo(); + [CallingConvention(.Stdcall),CLink] static extern char8* Debugger_GetThreadInfo(); @@ -967,6 +970,14 @@ namespace IDE.Debugger outStr.Append(str); } + public void GetProcessInfo(String outProcessInfo) + { + if (!mIsRunning) + return; + char8* strPtr = Debugger_GetProcessInfo(); + outProcessInfo.Append(strPtr); + } + public void GetThreadInfo(String outThreadInfo) { if (!mIsRunning) diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 1a36f0ad..74dc43c2 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -199,6 +199,7 @@ namespace IDE public CallStackPanel mCallStackPanel; public ErrorsPanel mErrorsPanel; public BreakpointPanel mBreakpointPanel; + public DiagnosticsPanel mDiagnosticsPanel; public ModulePanel mModulePanel; public ThreadPanel mThreadPanel; public ProfilePanel mProfilePanel; @@ -659,6 +660,7 @@ namespace IDE RemoveAndDelete!(mMemoryPanel); RemoveAndDelete!(mCallStackPanel); RemoveAndDelete!(mBreakpointPanel); + RemoveAndDelete!(mDiagnosticsPanel); RemoveAndDelete!(mModulePanel); RemoveAndDelete!(mThreadPanel); RemoveAndDelete!(mProfilePanel); @@ -746,6 +748,7 @@ namespace IDE dlg(mCallStackPanel); dlg(mErrorsPanel); dlg(mBreakpointPanel); + dlg(mDiagnosticsPanel); dlg(mModulePanel); dlg(mThreadPanel); dlg(mProfilePanel); @@ -4515,6 +4518,12 @@ namespace IDE ShowPanel(mBreakpointPanel, "Breakpoints"); } + [IDECommand] + public void ShowDiagnostics() + { + ShowPanel(mDiagnosticsPanel, "Diagnostics"); + } + [IDECommand] public void ShowModules() { @@ -5093,16 +5102,17 @@ namespace IDE ////////// subMenu = root.AddMenuItem("&View"); - AddMenuItem(subMenu, "A&utoComplete", "Show Autocomplete Panel"); + AddMenuItem(subMenu, "AutoComplet&e", "Show Autocomplete Panel"); AddMenuItem(subMenu, "&Auto Watches", "Show Auto Watches"); AddMenuItem(subMenu, "&Breakpoints", "Show Breakpoints"); AddMenuItem(subMenu, "&Call Stack", "Show Call Stack"); AddMenuItem(subMenu, "C&lass View", "Show Class View"); + AddMenuItem(subMenu, "&Diagnostics", "Show Diagnostics"); AddMenuItem(subMenu, "E&rrors", "Show Errors"); AddMenuItem(subMenu, "&Find Results", "Show Find Results"); AddMenuItem(subMenu, "&Immediate Window", "Show Immediate"); AddMenuItem(subMenu, "&Memory", "Show Memory"); - AddMenuItem(subMenu, "Mo&dules", "Show Modules"); + AddMenuItem(subMenu, "Mod&ules", "Show Modules"); AddMenuItem(subMenu, "&Output", "Show Output"); AddMenuItem(subMenu, "&Profiler", "Show Profiler"); AddMenuItem(subMenu, "&Threads", "Show Threads"); @@ -10771,6 +10781,8 @@ namespace IDE mCallStackPanel.mAutoDelete = false; mBreakpointPanel = new BreakpointPanel(); mBreakpointPanel.mAutoDelete = false; + mDiagnosticsPanel = new DiagnosticsPanel(); + mDiagnosticsPanel.mAutoDelete = false; mErrorsPanel = new ErrorsPanel(); mErrorsPanel.mAutoDelete = false; mModulePanel = new ModulePanel(); diff --git a/IDE/src/Settings.bf b/IDE/src/Settings.bf index 00374e83..d281e9dd 100644 --- a/IDE/src/Settings.bf +++ b/IDE/src/Settings.bf @@ -489,19 +489,20 @@ namespace IDE Add("Scope Next", "Alt+Down"); Add("Set Next Statement", "Ctrl+Shift+F10"); Add("Show Auto Watches", "Ctrl+Alt+A"); - Add("Show Autocomplete Panel", "Ctrl+Alt+U"); + Add("Show Autocomplete Panel", "Ctrl+Alt+E"); Add("Show Breakpoints", "Ctrl+Alt+B"); Add("Show Call Stack", "Ctrl+Alt+C"); Add("Show Class View", "Ctrl+Alt+L"); Add("Show Current", "Alt+C"); - Add("Show Errors", "Ctrl+Alt+E"); + Add("Show Errors", "Ctrl+Alt+R"); + Add("Show Diagnostics", "Ctrl+Alt+D"); Add("Show Error Next", "Ctrl+Shift+F12"); Add("Show File Externally", "Ctrl+Tilde"); Add("Show Find Results", "Ctrl+Alt+F"); Add("Show Fixit", "Ctrl+Period"); Add("Show Immediate", "Ctrl+Alt+I"); Add("Show Memory", "Ctrl+Alt+M"); - Add("Show Modules", "Ctrl+Alt+D"); + Add("Show Modules", "Ctrl+Alt+U"); Add("Show Output", "Ctrl+Alt+O"); Add("Show Profiler", "Ctrl+Alt+P"); Add("Show QuickWatch", "Shift+Alt+W"); diff --git a/IDE/src/ui/DiagnosticsPanel.bf b/IDE/src/ui/DiagnosticsPanel.bf new file mode 100644 index 00000000..1b0235e9 --- /dev/null +++ b/IDE/src/ui/DiagnosticsPanel.bf @@ -0,0 +1,57 @@ +using System; +using Beefy.utils; +using System.Diagnostics; + +namespace IDE.ui +{ + class DiagnosticsPanel : Panel + { + Stopwatch mSampleStopwatch = new .() ~ delete _; + int mSampleKernelTime; + int mSampleUserTime; + + public this() + { + mSampleStopwatch.Start(); + } + + public override void Update() + { + String procInfo = scope .(); + gApp.mDebugger.GetProcessInfo(procInfo); + + int virtualMem = 0; + int workingMem = 0; + int kernelTime = 0; + int userTime = 0; + + for (let line in procInfo.Split('\n')) + { + if (line.IsEmpty) + break; + + var lineEnum = line.Split('\t'); + let category = lineEnum.GetNext().Value; + let valueSV = lineEnum.GetNext().Value; + let value = int64.Parse(valueSV).Value; + + switch (category) + { + case "WorkingMemory": workingMem = value; + case "VirtualMemory": virtualMem = value; + case "KernelTime": kernelTime = value; + case "UserTime": userTime = value; + } + } + + + } + + public override void Serialize(StructuredData data) + { + base.Serialize(data); + + data.Add("Type", "DiagnosticsPanel"); + } + } +} diff --git a/IDE/src/ui/Panel.bf b/IDE/src/ui/Panel.bf index df7c2a95..964e2f3d 100644 --- a/IDE/src/ui/Panel.bf +++ b/IDE/src/ui/Panel.bf @@ -143,6 +143,10 @@ namespace IDE.ui { panel = gApp.mMemoryPanel; } + else if (type == "DiagnosticsPanel") + { + panel = gApp.mDiagnosticsPanel; + } else if (type == "AutoCompletePanel") { panel = gApp.mAutoCompletePanel; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index eddfdd65..ee3f1269 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -3825,64 +3825,9 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar } if ((mResultLocalVar != NULL) && (fieldInstance->mMergedDataIdx != -1)) - { - int minMergedDataIdx = fieldInstance->mMergedDataIdx; - int maxMergedDataIdx = minMergedDataIdx + 1; - if (resolvedFieldType->IsStruct()) - maxMergedDataIdx = minMergedDataIdx + resolvedFieldType->ToTypeInstance()->mMergedFieldDataCount; - - if (curCheckType->mIsUnion) - { - for (auto& checkFieldInstance : curCheckType->mFieldInstances) - { - if (&checkFieldInstance == fieldInstance) - continue; - - if (checkFieldInstance.mDataIdx == fieldInstance->mDataIdx) - { - int checkMinMergedDataIdx = checkFieldInstance.mMergedDataIdx; - int checkMaxMergedDataIdx = checkMinMergedDataIdx + 1; - if (checkFieldInstance.GetResolvedType()->IsStruct()) - checkMaxMergedDataIdx = checkMinMergedDataIdx + checkFieldInstance.mResolvedType->ToTypeInstance()->mMergedFieldDataCount; - - minMergedDataIdx = BF_MIN(minMergedDataIdx, checkMinMergedDataIdx); - maxMergedDataIdx = BF_MAX(maxMergedDataIdx, checkMaxMergedDataIdx); - } - } - } - - int fieldIdx = mResultLocalVarField - 1; - if (fieldIdx == -1) - { - mResultLocalVarField = minMergedDataIdx + 1; - } - else - { - fieldIdx += minMergedDataIdx; - mResultLocalVarField = fieldIdx + 1; - } - mResultLocalVarFieldCount = maxMergedDataIdx - minMergedDataIdx; - mResultLocalVarRefNode = targetSrc; - - /*int fieldIdx = (mResultLocalVarIdx >> 16) - 1; - if (fieldIdx == -1) - { - mResultLocalVarField = fieldInstance->mMergedDataIdx + 1; - } - else - { - fieldIdx += fieldInstance->mMergedDataIdx; - mResultLocalVarField = fieldIdx + 1; - } - mResultLocalVarFieldCount = 1; - if (fieldInstance->mType->IsStruct()) - { - auto fieldTypeInstance = fieldInstance->mType->ToTypeInstance(); - mResultLocalVarFieldCount = fieldTypeInstance->mMergedFieldDataCount; - } - mResultLocalVarRefNode = targetSrc;*/ - - + { + fieldInstance->GetDataRange(mResultLocalVarField, mResultLocalVarFieldCount); + mResultLocalVarRefNode = targetSrc; } if ((curCheckType->IsIncomplete()) && (!curCheckType->mNeedsMethodProcessing)) @@ -15135,7 +15080,7 @@ void BfExprEvaluator::MarkResultAssigned() //return; auto localVar = mResultLocalVar; - int fieldIdx = mResultLocalVarField - 1; + int fieldIdx = mResultLocalVarField - 1; int count = mResultLocalVarFieldCount; if (fieldIdx == -1) count = 1; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index f6fc50b4..a3bdce75 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1098,7 +1098,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen) //mBfIRBuilder->mDbgVerifyCodeGen = true; if ( (mModuleName == "-") - //|| (mModuleName == "Tests_FuncRefs_Class") + //|| (mModuleName == "BeefTest2_ClearColorValue") //|| (mModuleName == "Tests_FuncRefs") ) mBfIRBuilder->mDbgVerifyCodeGen = true; @@ -3744,19 +3744,21 @@ void BfModule::MarkFieldInitialized(BfFieldInstance* fieldInstance) auto fieldType = fieldInstance->GetResolvedType(); if ((fieldInstance->mMergedDataIdx != -1) && (mCurMethodState != NULL)) { - int fieldDataCount = 1; - if (fieldType->IsStruct()) - { - auto structTypeInst = fieldType->ToTypeInstance(); - fieldDataCount = structTypeInst->mMergedFieldDataCount; - } + int fieldIdx = 0; + int fieldCount = 0; + fieldInstance->GetDataRange(fieldIdx, fieldCount); + fieldIdx--; + int count = fieldCount; + if (fieldIdx == -1) + count = 1; + //TODO: Under what circumstances could 'thisVariable' be NULL? auto thisVariable = GetThisVariable(); if (thisVariable != NULL) { - for (int i = 0; i < fieldDataCount; i++) - mCurMethodState->LocalDefined(thisVariable, fieldInstance->mMergedDataIdx + i); + for (int i = 0; i < count; i++) + mCurMethodState->LocalDefined(thisVariable, fieldIdx + i); } } } @@ -14979,7 +14981,14 @@ void BfModule::EmitCtorBody(bool& skipBody) { // Failed } - auto assignValue = GetFieldInitializerValue(fieldInst); + auto assignValue = GetFieldInitializerValue(fieldInst); + + if (mCurTypeInstance->IsUnion()) + { + auto fieldPtrType = CreatePointerType(fieldInst->mResolvedType); + fieldAddr = mBfIRBuilder->CreateBitCast(fieldAddr, mBfIRBuilder->MapType(fieldPtrType)); + } + if ((fieldAddr) && (assignValue)) mBfIRBuilder->CreateStore(assignValue.mValue, fieldAddr); } diff --git a/IDEHelper/DebugManager.cpp b/IDEHelper/DebugManager.cpp index 88afc397..030d7279 100644 --- a/IDEHelper/DebugManager.cpp +++ b/IDEHelper/DebugManager.cpp @@ -1299,16 +1299,23 @@ BF_EXPORT void BF_CALLTYPE Debugger_ForegroundTarget() //BF_ASSERT(worked); } +BF_EXPORT const char* BF_CALLTYPE Debugger_GetProcessInfo() +{ + String& outString = *gTLStrReturn.Get(); + outString = gDebugger->GetProcessInfo(); + return outString.c_str(); +} + BF_EXPORT const char* BF_CALLTYPE Debugger_GetThreadInfo() { - String& outString = *gTLStrReturn.Get(); + String& outString = *gTLStrReturn.Get(); outString = gDebugger->GetThreadInfo(); return outString.c_str(); } BF_EXPORT void BF_CALLTYPE Debugger_SetActiveThread(int threadId) { - gDebugger->SetActiveThread(threadId); + gDebugger->SetActiveThread(threadId); } BF_EXPORT int BF_CALLTYPE Debugger_GetActiveThread() diff --git a/IDEHelper/Debugger.h b/IDEHelper/Debugger.h index d80c6e4b..3424ef6b 100644 --- a/IDEHelper/Debugger.h +++ b/IDEHelper/Debugger.h @@ -283,6 +283,7 @@ public: virtual String GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) = 0; virtual String GetAutoLocals(int callStackIdx, bool showRegs) = 0; virtual String CompactChildExpression(const StringImpl& expr, const StringImpl& parentExpr, int callStackIdx) = 0; + virtual String GetProcessInfo() = 0; virtual String GetThreadInfo() = 0; virtual void SetActiveThread(int threadId) = 0; virtual int GetActiveThread() = 0; diff --git a/IDEHelper/WinDebugger.cpp b/IDEHelper/WinDebugger.cpp index 5947c03d..adb18cac 100644 --- a/IDEHelper/WinDebugger.cpp +++ b/IDEHelper/WinDebugger.cpp @@ -10201,6 +10201,31 @@ String WinDebugger::CompactChildExpression(const StringImpl& expr, const StringI return result; } +String WinDebugger::GetProcessInfo() +{ + AutoCrit autoCrit(mDebugManager->mCritSect); + + if ((mActiveThread == NULL) && (!mIsRunning)) + return ""; + + FILETIME creationTime = { 0 }; + FILETIME exitTime = { 0 }; + FILETIME kernelTime = { 0 }; + FILETIME userTime = { 0 }; + GetProcessTimes(mProcessInfo.hProcess, &creationTime, &exitTime, &kernelTime, &userTime); + + String retStr; + PROCESS_MEMORY_COUNTERS memInfo = { 0 }; + GetProcessMemoryInfo(mProcessInfo.hProcess, &memInfo, sizeof(PROCESS_MEMORY_COUNTERS)); + + retStr += StrFormat("VirtualMemory\t%d\n", memInfo.PagefileUsage); + retStr += StrFormat("WorkingMemory\t%d\n", memInfo.WorkingSetSize); + retStr += StrFormat("KernelTime\t%lld\n", *(int64*)&kernelTime); + retStr += StrFormat("UserTime\t%lld\n", *(int64*)&userTime); + + return retStr; +} + String WinDebugger::GetThreadInfo() { AutoCrit autoCrit(mDebugManager->mCritSect); diff --git a/IDEHelper/WinDebugger.h b/IDEHelper/WinDebugger.h index 5f83b4dd..77a3f364 100644 --- a/IDEHelper/WinDebugger.h +++ b/IDEHelper/WinDebugger.h @@ -626,6 +626,7 @@ public: virtual String GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) override; virtual String GetAutoLocals(int callStackIdx, bool showRegs) override; virtual String CompactChildExpression(const StringImpl& expr, const StringImpl& parentExpr, int callStackIdx) override; + virtual String GetProcessInfo() override; virtual String GetThreadInfo() override; virtual void SetActiveThread(int threadId) override; virtual int GetActiveThread() override;