From bc634e9d377bee90025f54c7224b4fee460c3928 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 13 Aug 2021 13:44:29 +0200 Subject: [PATCH] Refactor Tracy source locations to be static #597 --- Source/Engine/Content/Assets/VisualScript.cpp | 7 ++- Source/Engine/Content/Assets/VisualScript.h | 4 ++ Source/Engine/Profiler/ProfilerCPU.h | 26 +++++------ Source/Engine/Profiler/ProfilerSrcLoc.h | 18 ++++++++ .../Scripting/ManagedCLR/MMethod.Mono.cpp | 9 +++- Source/Engine/Scripting/ManagedCLR/MMethod.h | 4 ++ .../Engine/Scripting/Scripting.Internal.cpp | 45 ++++++++++++++++++- .../ThirdParty/tracy/client/TracyScoped.hpp | 17 +++++++ .../ThirdParty/tracy/common/TracySystem.hpp | 1 + .../Bindings/BindingsGenerator.Cpp.cs | 4 +- 10 files changed, 115 insertions(+), 20 deletions(-) create mode 100644 Source/Engine/Profiler/ProfilerSrcLoc.h diff --git a/Source/Engine/Content/Assets/VisualScript.cpp b/Source/Engine/Content/Assets/VisualScript.cpp index 184360f1f..fe3279856 100644 --- a/Source/Engine/Content/Assets/VisualScript.cpp +++ b/Source/Engine/Content/Assets/VisualScript.cpp @@ -1222,6 +1222,11 @@ Asset::LoadResult VisualScript::load() method.ProfilerName.Get()[assetName.Length()] = ':'; method.ProfilerName.Get()[assetName.Length() + 1] = ':'; Platform::MemoryCopy(method.ProfilerName.Get() + assetName.Length() + 2, method.Name.Get(), method.Name.Length()); + method.ProfilerData.name = method.ProfilerName.Get(); + method.ProfilerData.function = method.Name.Get(); + method.ProfilerData.file = nullptr; + method.ProfilerData.line = 0; + method.ProfilerData.color = 0; } #endif @@ -2139,7 +2144,7 @@ VisualScriptingBinaryModule* VisualScripting::GetBinaryModule() Variant VisualScripting::Invoke(VisualScript::Method* method, ScriptingObject* instance, Span parameters) { CHECK_RETURN(method && method->Script->IsLoaded(), Variant::Zero); - PROFILE_CPU_NAMED(*method->ProfilerName); + PROFILE_CPU_SRC_LOC(method->ProfilerData); // Add to the calling stack ScopeContext scope; diff --git a/Source/Engine/Content/Assets/VisualScript.h b/Source/Engine/Content/Assets/VisualScript.h index db6b5ebd3..3ea98e9a3 100644 --- a/Source/Engine/Content/Assets/VisualScript.h +++ b/Source/Engine/Content/Assets/VisualScript.h @@ -5,6 +5,9 @@ #include "../BinaryAsset.h" #include "Engine/Scripting/BinaryModule.h" #include "Engine/Visject/VisjectGraph.h" +#if COMPILE_WITH_PROFILER +#include "Engine/Profiler/ProfilerSrcLoc.h" +#endif #define VISUAL_SCRIPT_GRAPH_MAX_CALL_STACK 250 #define VISUAL_SCRIPT_DEBUGGING USE_EDITOR @@ -118,6 +121,7 @@ public: Array> ParamNames; #if COMPILE_WITH_PROFILER StringAnsi ProfilerName; + SourceLocationData ProfilerData; #endif }; diff --git a/Source/Engine/Profiler/ProfilerCPU.h b/Source/Engine/Profiler/ProfilerCPU.h index 2a48e6c15..7ffdc85eb 100644 --- a/Source/Engine/Profiler/ProfilerCPU.h +++ b/Source/Engine/Profiler/ProfilerCPU.h @@ -386,33 +386,31 @@ struct TIsPODType enum { Value = true }; }; +#include "ProfilerSrcLoc.h" + // Shortcut macros for profiling a single code block execution on CPU // Use ZoneTransient for Tracy for code that can be hot-reloaded (eg. in Editor) or if name can be a variable +#define PROFILE_CPU_USE_TRANSIENT_DATA 0 -#define PROFILE_CPU_NAMED(name) ZoneTransientN(___tracy_scoped_zone, name, true); ScopeProfileBlockCPU ProfileBlockCPU(name) - -#if defined(_MSC_VER) - -#if USE_EDITOR -#define PROFILE_CPU() ZoneTransient(___tracy_scoped_zone, true); ScopeProfileBlockCPU ProfileBlockCPU(TEXT(__FUNCTION__)) -#else -#define PROFILE_CPU() ZoneNamed(___tracy_scoped_zone, true); ScopeProfileBlockCPU ProfileBlockCPU(TEXT(__FUNCTION__)) -#endif - -#else - -#if USE_EDITOR +#if PROFILE_CPU_USE_TRANSIENT_DATA #define PROFILE_CPU() ZoneTransient(___tracy_scoped_zone, true); ScopeProfileBlockCPU ProfileBlockCPU(__FUNCTION__) +#define PROFILE_CPU_NAMED(name) ZoneTransientN(___tracy_scoped_zone, name, true); ScopeProfileBlockCPU ProfileBlockCPU(name) #else #define PROFILE_CPU() ZoneNamed(___tracy_scoped_zone, true); ScopeProfileBlockCPU ProfileBlockCPU(__FUNCTION__) +#define PROFILE_CPU_NAMED(name) ZoneNamedN(___tracy_scoped_zone, name, true); ScopeProfileBlockCPU ProfileBlockCPU(name) #endif +#ifdef TRACY_ENABLE +#define PROFILE_CPU_SRC_LOC(srcLoc) tracy::ScopedZone ___tracy_scoped_zone( (tracy::SourceLocationData*)&(srcLoc) ); ScopeProfileBlockCPU ProfileBlockCPU((srcLoc).name) +#else +#define PROFILE_CPU_SRC_LOC(srcLoc) ScopeProfileBlockCPU ProfileBlockCPU((srcLoc).name) #endif #else // Empty macros for disabled profiler -#define PROFILE_CPU_NAMED(name) #define PROFILE_CPU() +#define PROFILE_CPU_NAMED(name) +#define PROFILE_CPU_SRC_LOC(srcLoc) #endif diff --git a/Source/Engine/Profiler/ProfilerSrcLoc.h b/Source/Engine/Profiler/ProfilerSrcLoc.h new file mode 100644 index 000000000..6ee116668 --- /dev/null +++ b/Source/Engine/Profiler/ProfilerSrcLoc.h @@ -0,0 +1,18 @@ +// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. + +#pragma once + +#if COMPILE_WITH_PROFILER + +#include "Engine/Core/Types/BaseTypes.h" + +struct FLAXENGINE_API SourceLocationData +{ + const char* name; + const char* function; + const char* file; + uint32 line; + uint32 color; +}; + +#endif diff --git a/Source/Engine/Scripting/ManagedCLR/MMethod.Mono.cpp b/Source/Engine/Scripting/ManagedCLR/MMethod.Mono.cpp index 3fb8a16a4..6abff601d 100644 --- a/Source/Engine/Scripting/ManagedCLR/MMethod.Mono.cpp +++ b/Source/Engine/Scripting/ManagedCLR/MMethod.Mono.cpp @@ -60,18 +60,23 @@ MMethod::MMethod(MonoMethod* monoMethod, const char* name, MClass* parentClass) ProfilerName.Get()[className.Length()] = ':'; ProfilerName.Get()[className.Length() + 1] = ':'; Platform::MemoryCopy(ProfilerName.Get() + className.Length() + 2, _name.Get(), _name.Length()); + ProfilerData.name = ProfilerName.Get(); + ProfilerData.function = _name.Get(); + ProfilerData.file = nullptr; + ProfilerData.line = 0; + ProfilerData.color = 0; #endif } MonoObject* MMethod::Invoke(void* instance, void** params, MonoObject** exception) const { - PROFILE_CPU_NAMED(*ProfilerName); + PROFILE_CPU_SRC_LOC(ProfilerData); return mono_runtime_invoke(_monoMethod, instance, params, exception); } MonoObject* MMethod::InvokeVirtual(MonoObject* instance, void** params, MonoObject** exception) const { - PROFILE_CPU_NAMED(*ProfilerName); + PROFILE_CPU_SRC_LOC(ProfilerData); MonoMethod* virtualMethod = mono_object_get_virtual_method(instance, _monoMethod); return mono_runtime_invoke(virtualMethod, instance, params, exception); } diff --git a/Source/Engine/Scripting/ManagedCLR/MMethod.h b/Source/Engine/Scripting/ManagedCLR/MMethod.h index 60701a9b3..46320013f 100644 --- a/Source/Engine/Scripting/ManagedCLR/MMethod.h +++ b/Source/Engine/Scripting/ManagedCLR/MMethod.h @@ -3,6 +3,9 @@ #pragma once #include "Engine/Core/Collections/Array.h" +#if COMPILE_WITH_PROFILER +#include "Engine/Profiler/ProfilerSrcLoc.h" +#endif #include "MTypes.h" /// @@ -42,6 +45,7 @@ public: #if COMPILE_WITH_PROFILER MString ProfilerName; + SourceLocationData ProfilerData; #endif #if USE_MONO diff --git a/Source/Engine/Scripting/Scripting.Internal.cpp b/Source/Engine/Scripting/Scripting.Internal.cpp index b437c442e..1c07d3cf4 100644 --- a/Source/Engine/Scripting/Scripting.Internal.cpp +++ b/Source/Engine/Scripting/Scripting.Internal.cpp @@ -9,13 +9,29 @@ #include "Engine/Scripting/ManagedCLR/MUtils.h" #include "Engine/Core/ObjectsRemovalService.h" #include "Engine/Profiler/Profiler.h" +#if TRACY_ENABLE && !PROFILE_CPU_USE_TRANSIENT_DATA +#include "Engine/Core/Collections/ChunkedArray.h" +#endif +#include "Engine/Core/Types/Pair.h" #include "Engine/Threading/Threading.h" #include namespace ProfilerInternal { #if COMPILE_WITH_PROFILER - Array ManagedEventsGPU; + Array> ManagedEventsGPU; +#if TRACY_ENABLE && !PROFILE_CPU_USE_TRANSIENT_DATA + CriticalSection ManagedSourceLocationsLocker; + + struct Location + { + String Name; + StringAnsi NameAnsi; + tracy::SourceLocationData SrcLocation; + }; + + ChunkedArray ManagedSourceLocations; +#endif #endif void BeginEvent(MonoString* nameObj) @@ -24,7 +40,34 @@ namespace ProfilerInternal const StringView name((const Char*)mono_string_chars(nameObj), mono_string_length(nameObj)); ProfilerCPU::BeginEvent(*name); #if TRACY_ENABLE +#if PROFILE_CPU_USE_TRANSIENT_DATA tracy::ScopedZone::Begin(__LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name.Get(), name.Length() ); +#else + ScopeLock lock(ManagedSourceLocationsLocker); + tracy::SourceLocationData* srcLoc = nullptr; + for (auto& e = ManagedSourceLocations.Begin(); e.IsNotEnd(); ++e) + { + if (name == e->Name) + { + srcLoc = &e->SrcLocation; + break; + } + } + if (!srcLoc) + { + auto& e = ManagedSourceLocations.AddOne(); + e.Name = name; + e.NameAnsi = name.Get(); + srcLoc = &e.SrcLocation; + srcLoc->name = e.NameAnsi.Get(); + srcLoc->function = nullptr; + srcLoc->file = nullptr; + srcLoc->line = 0; + srcLoc->color = 0; + } + //static constexpr tracy::SourceLocationData tracySrcLoc{ nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; + tracy::ScopedZone::Begin(srcLoc); +#endif #endif #endif } diff --git a/Source/ThirdParty/tracy/client/TracyScoped.hpp b/Source/ThirdParty/tracy/client/TracyScoped.hpp index 5de03105c..b18f02388 100644 --- a/Source/ThirdParty/tracy/client/TracyScoped.hpp +++ b/Source/ThirdParty/tracy/client/TracyScoped.hpp @@ -12,8 +12,22 @@ namespace tracy { +void ScopedZone::Begin(const SourceLocationData* srcloc) +{ +#ifdef TRACY_ON_DEMAND + if (!GetProfiler().IsConnected()) return; +#endif + TracyLfqPrepare( QueueType::ZoneBegin ); + MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); + MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc ); + TracyLfqCommit; +} + void ScopedZone::Begin(uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const Char* name, size_t nameSz) { +#ifdef TRACY_ON_DEMAND + if (!GetProfiler().IsConnected()) return; +#endif TracyLfqPrepare( QueueType::ZoneBeginAllocSrcLoc ); const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz ); MemWrite( &item->zoneBegin.time, Profiler::GetTime() ); @@ -23,6 +37,9 @@ void ScopedZone::Begin(uint32_t line, const char* source, size_t sourceSz, const void ScopedZone::End() { +#ifdef TRACY_ON_DEMAND + if (!GetProfiler().IsConnected()) return; +#endif TracyLfqPrepare( QueueType::ZoneEnd ); MemWrite( &item->zoneEnd.time, Profiler::GetTime() ); TracyLfqCommit; diff --git a/Source/ThirdParty/tracy/common/TracySystem.hpp b/Source/ThirdParty/tracy/common/TracySystem.hpp index b2d0e8dda..8a699886b 100644 --- a/Source/ThirdParty/tracy/common/TracySystem.hpp +++ b/Source/ThirdParty/tracy/common/TracySystem.hpp @@ -46,6 +46,7 @@ struct TRACY_API SourceLocationData class TRACY_API ScopedZone { public: + static void Begin( const SourceLocationData* srcloc ); static void Begin( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const Char* name, size_t nameSz ); static void End(); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index e61a2cf0a..07d9b490a 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1028,7 +1028,7 @@ namespace Flax.Build.Bindings contents.AppendLine(" auto scriptVTable = (MMethod**)managedTypePtr->Script.ScriptVTable;"); contents.AppendLine($" ASSERT(scriptVTable && scriptVTable[{scriptVTableIndex}]);"); contents.AppendLine($" auto method = scriptVTable[{scriptVTableIndex}];"); - contents.AppendLine(" PROFILE_CPU_NAMED(*method->ProfilerName);"); + contents.AppendLine($" PROFILE_CPU_NAMED(\"{classInfo.FullNameManaged}::{functionInfo.Name}\");"); contents.AppendLine(" MonoObject* exception = nullptr;"); contents.AppendLine(" auto prevWrapperCallInstance = WrapperCallInstance;"); @@ -1290,7 +1290,7 @@ namespace Flax.Build.Bindings contents.Append(" if (!mmethod)").AppendLine(); contents.AppendFormat(" mmethod = {1}::TypeInitializer.GetType().ManagedClass->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine(); contents.Append(" CHECK(mmethod);").AppendLine(); - contents.Append(" PROFILE_CPU_NAMED(*mmethod->ProfilerName);").AppendLine(); + contents.Append($" PROFILE_CPU_NAMED(\"{classInfo.FullNameManaged}::On{eventInfo.Name}\");").AppendLine(); contents.Append(" MonoObject* exception = nullptr;").AppendLine(); if (paramsCount == 0) contents.AppendLine(" void** params = nullptr;");