From b8501956f920740e7f369b1c428f89209a9937f3 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Thu, 28 Feb 2019 20:16:19 +0100 Subject: [PATCH] Lua callstack sending. --- TracyLua.hpp | 206 +++++++++++++++++++++++++++++++++++++++++- common/TracyQueue.hpp | 2 + 2 files changed, 206 insertions(+), 2 deletions(-) diff --git a/TracyLua.hpp b/TracyLua.hpp index a9c53710..a3ba92c0 100644 --- a/TracyLua.hpp +++ b/TracyLua.hpp @@ -23,6 +23,10 @@ static inline void LuaRegister( lua_State* L ) lua_pushcfunction( L, detail::noop ); lua_setfield( L, -2, "ZoneBeginN" ); lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "ZoneBeginS" ); + lua_pushcfunction( L, detail::noop ); + lua_setfield( L, -2, "ZoneBeginNS" ); + lua_pushcfunction( L, detail::noop ); lua_setfield( L, -2, "ZoneEnd" ); lua_pushcfunction( L, detail::noop ); lua_setfield( L, -2, "ZoneText" ); @@ -81,6 +85,18 @@ static inline void LuaRemove( char* script ) memset( script, ' ', end - script ); script = end; } + else if( strncmp( script + 10, "BeginS(", 7 ) == 0 ) + { + auto end = FindEnd( script + 17 ); + memset( script, ' ', end - script ); + script = end; + } + else if( strncmp( script + 10, "BeginNS(", 8 ) == 0 ) + { + auto end = FindEnd( script + 18 ); + memset( script, ' ', end - script ); + script = end; + } else { script += 10; @@ -125,7 +141,53 @@ LuaZoneState& GetLuaZoneState(); namespace detail { -static inline int LuaZoneBegin( lua_State* L ) +static inline void SendLuaCallstack( lua_State* L, uint32_t depth ) +{ + assert( depth <= 64 ); + lua_Debug dbg[64]; + const char* func[64]; + uint32_t fsz[64]; + uint32_t ssz[64]; + uint32_t spaceNeeded = 4; // cnt + + uint32_t cnt; + for( cnt=0; cntget_tail_index(); + auto item = token->enqueue_begin( magic ); + MemWrite( &item->hdr.type, QueueType::CallstackAlloc ); + MemWrite( &item->callstack.ptr, (uint64_t)ptr ); + MemWrite( &item->callstack.thread, GetThreadHandle() ); + tail.store( magic + 1, std::memory_order_release ); +} + +static inline int LuaZoneBeginS( lua_State* L ) { #ifdef TRACY_ON_DEMAND const auto zoneCnt = GetLuaZoneState().counter++; @@ -176,10 +238,18 @@ static inline int LuaZoneBegin( lua_State* L ) MemWrite( &item->zoneBegin.thread, GetThreadHandle() ); MemWrite( &item->zoneBegin.srcloc, (uint64_t)ptr ); tail.store( magic + 1, std::memory_order_release ); + +#ifdef TRACY_CALLSTACK + const uint32_t depth = TRACY_CALLSTACK; +#else + const auto depth = uint32_t( lua_tointeger( L, 1 ) ); +#endif + SendLuaCallstack( L, depth ); + return 0; } -static inline int LuaZoneBeginN( lua_State* L ) +static inline int LuaZoneBeginNS( lua_State* L ) { #ifdef TRACY_ON_DEMAND const auto zoneCnt = GetLuaZoneState().counter++; @@ -234,9 +304,137 @@ static inline int LuaZoneBeginN( lua_State* L ) MemWrite( &item->zoneBegin.thread, GetThreadHandle() ); MemWrite( &item->zoneBegin.srcloc, (uint64_t)ptr ); tail.store( magic + 1, std::memory_order_release ); + +#ifdef TRACY_CALLSTACK + const uint32_t depth = TRACY_CALLSTACK; +#else + const auto depth = uint32_t( lua_tointeger( L, 1 ) ); +#endif + SendLuaCallstack( L, depth ); + return 0; } +static inline int LuaZoneBegin( lua_State* L ) +{ +#ifdef TRACY_CALLSTACK + return LuaZoneBeginS( L ); +#else +#ifdef TRACY_ON_DEMAND + const auto zoneCnt = GetLuaZoneState().counter++; + if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0; + GetLuaZoneState().active = GetProfiler().IsConnected(); + if( !GetLuaZoneState().active ) return 0; +#endif + + const uint32_t color = Color::DeepSkyBlue3; + + lua_Debug dbg; + lua_getstack( L, 1, &dbg ); + lua_getinfo( L, "Snl", &dbg ); + + const uint32_t line = dbg.currentline; + const auto func = dbg.name ? dbg.name : dbg.short_src; + const auto fsz = strlen( func ); + const auto ssz = strlen( dbg.source ); + + // Data layout: + // 4b payload size + // 4b color + // 4b source line + // fsz function name + // 1b null terminator + // ssz source file name + // 1b null terminator + const uint32_t sz = uint32_t( 4 + 4 + 4 + fsz + 1 + ssz + 1 ); + auto ptr = (char*)tracy_malloc( sz ); + memcpy( ptr, &sz, 4 ); + memcpy( ptr + 4, &color, 4 ); + memcpy( ptr + 8, &line, 4 ); + memcpy( ptr + 12, func, fsz+1 ); + memcpy( ptr + 12 + fsz + 1, dbg.source, ssz + 1 ); + + Magic magic; + auto token = GetToken(); + auto& tail = token->get_tail_index(); + auto item = token->enqueue_begin( magic ); + MemWrite( &item->hdr.type, QueueType::ZoneBeginAllocSrcLoc ); +#ifdef TRACY_RDTSCP_OPT + MemWrite( &item->zoneBegin.time, Profiler::GetTime( item->zoneBegin.cpu ) ); +#else + uint32_t cpu; + MemWrite( &item->zoneBegin.time, Profiler::GetTime( cpu ) ); + MemWrite( &item->zoneBegin.cpu, cpu ); +#endif + MemWrite( &item->zoneBegin.thread, GetThreadHandle() ); + MemWrite( &item->zoneBegin.srcloc, (uint64_t)ptr ); + tail.store( magic + 1, std::memory_order_release ); + return 0; +#endif +} + +static inline int LuaZoneBeginN( lua_State* L ) +{ +#ifdef TRACY_CALLSTACK + return LuaZoneBeginNS( L ); +#else +#ifdef TRACY_ON_DEMAND + const auto zoneCnt = GetLuaZoneState().counter++; + if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0; + GetLuaZoneState().active = GetProfiler().IsConnected(); + if( !GetLuaZoneState().active ) return 0; +#endif + + const uint32_t color = Color::DeepSkyBlue3; + + lua_Debug dbg; + lua_getstack( L, 1, &dbg ); + lua_getinfo( L, "Snl", &dbg ); + + const uint32_t line = dbg.currentline; + const auto func = dbg.name ? dbg.name : dbg.short_src; + size_t nsz; + const auto name = lua_tolstring( L, 1, &nsz ); + const auto fsz = strlen( func ); + const auto ssz = strlen( dbg.source ); + + // Data layout: + // 4b payload size + // 4b color + // 4b source line + // fsz function name + // 1b null terminator + // ssz source file name + // 1b null terminator + // nsz zone name + const uint32_t sz = uint32_t( 4 + 4 + 4 + fsz + 1 + ssz + 1 + nsz ); + auto ptr = (char*)tracy_malloc( sz ); + memcpy( ptr, &sz, 4 ); + memcpy( ptr + 4, &color, 4 ); + memcpy( ptr + 8, &line, 4 ); + memcpy( ptr + 12, func, fsz+1 ); + memcpy( ptr + 12 + fsz + 1, dbg.source, ssz + 1 ); + memcpy( ptr + 12 + fsz + 1 + ssz + 1, name, nsz ); + + Magic magic; + auto token = GetToken(); + auto& tail = token->get_tail_index(); + auto item = token->enqueue_begin( magic ); + MemWrite( &item->hdr.type, QueueType::ZoneBeginAllocSrcLoc ); +#ifdef TRACY_RDTSCP_OPT + MemWrite( &item->zoneBegin.time, Profiler::GetTime( item->zoneBegin.cpu ) ); +#else + uint32_t cpu; + MemWrite( &item->zoneBegin.time, Profiler::GetTime( cpu ) ); + MemWrite( &item->zoneBegin.cpu, cpu ); +#endif + MemWrite( &item->zoneBegin.thread, GetThreadHandle() ); + MemWrite( &item->zoneBegin.srcloc, (uint64_t)ptr ); + tail.store( magic + 1, std::memory_order_release ); + return 0; +#endif +} + static inline int LuaZoneEnd( lua_State* L ) { #ifdef TRACY_ON_DEMAND @@ -356,6 +554,10 @@ static inline void LuaRegister( lua_State* L ) lua_setfield( L, -2, "ZoneBegin" ); lua_pushcfunction( L, detail::LuaZoneBeginN ); lua_setfield( L, -2, "ZoneBeginN" ); + lua_pushcfunction( L, detail::LuaZoneBeginS ); + lua_setfield( L, -2, "ZoneBeginS" ); + lua_pushcfunction( L, detail::LuaZoneBeginNS ); + lua_setfield( L, -2, "ZoneBeginNS" ); lua_pushcfunction( L, detail::LuaZoneEnd ); lua_setfield( L, -2, "ZoneEnd" ); lua_pushcfunction( L, detail::LuaZoneText ); diff --git a/common/TracyQueue.hpp b/common/TracyQueue.hpp index 7246ffb2..939e715e 100644 --- a/common/TracyQueue.hpp +++ b/common/TracyQueue.hpp @@ -14,6 +14,7 @@ enum class QueueType : uint8_t ZoneBeginAllocSrcLoc, CallstackMemory, Callstack, + CallstackAlloc, Terminate, KeepAlive, Crash, @@ -327,6 +328,7 @@ static const size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), // allocated source location sizeof( QueueHeader ) + sizeof( QueueCallstackMemory ), sizeof( QueueHeader ) + sizeof( QueueCallstack ), + sizeof( QueueHeader ) + sizeof( QueueCallstack ), // callstack alloc // above items must be first sizeof( QueueHeader ), // terminate sizeof( QueueHeader ), // keep alive