-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add support for Tracy profiler (#1153)
* add support for Tracy profiler * add tracy client * add Aidan's StackContext Zone * a bit more documentation * doc cleanup * add HXCPP_TRACY_DISABLE_STACKS flag * put tracy include behind HXCPP_TRACY * move code to third party; move tracy into it's own cachable <files> section in haxe-target.xml * shift tracy telemetry into its own cpp file * fix incorrect signature * add global __hxcpp_tracy_* telemetry functions * add ctx to cppia-stackframe; fix sourcelocation's fullName * remove the dependency on haxe's stackframe context, use tracyZones vector instead * update docs * bug: fix InternalNew's parameter being used as linenumber in its HX_STACK_FRAME * fix wrong path in HX_STACK_FRAME * add HXCPP_TRACY_NO_EXIT & HXCPP_TRACY_ON_DEMAND support * added HXCPP_TRACY_INCLUDE_CALLSTACKS, use this to generate & include callstacks in the profiler zones * allocation tracking * add no-op gc alloc function to hxtelemetry implementation * Account for the same large object pointer appearing before collection * add HXCPP_TRACY_MEMORY * stack depth needs +1 * track large objects globally * eagerly free large objects * add __hxcpp_tracy_set_thread_name_and_group; disable custom GC ___tracy_source_location_data * new tracy telemetry header and hxcpp zone macro * Use hxcpp float * fix argument order in custom scope * Remove test zone function * line unique scope variable * callstack macro variant * fix HXCPP_TRACY_ZONE * zone count function * update docs & comments * update readme --------- Co-authored-by: Aidan Lee <[email protected]>
- Loading branch information
Showing
85 changed files
with
45,618 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef HX_TELEMETRY_TRACY_H | ||
#define HX_TELEMETRY_TRACY_H | ||
|
||
#ifndef HXCPP_TRACY | ||
#error "Error: HXCPP_TRACY must be defined." | ||
#endif | ||
|
||
#define TRACY_ENABLE | ||
#include <hxcpp.h> | ||
#include "../../project/thirdparty/tracy-0.11.1/tracy/TracyC.h" | ||
#include "../../project/thirdparty/tracy-0.11.1/tracy/Tracy.hpp" | ||
|
||
#ifdef HXCPP_TRACY_MEMORY | ||
#ifdef HXCPP_GC_MOVING | ||
#error "Error: HXCPP_TRACY_MEMORY is not supported when HXCPP_GC_MOVING is active." | ||
#endif | ||
#ifdef HXCPP_GC_GENERATIONAL | ||
#error "Error: HXCPP_TRACY_MEMORY is not supported when HXCPP_GC_GENERATIONAL is active." | ||
#endif | ||
#endif | ||
|
||
#ifdef HXCPP_TRACY_INCLUDE_CALLSTACKS | ||
#define HXCPP_TRACY_ZONE(name) \ | ||
::hx::strbuf TracyConcat(_hx_tracy_str_buffer, TracyLine); \ | ||
int TracyConcat(_hx_tracy_str_length, TracyLine); \ | ||
const char *TracyConcat(_hx_tracy_str_buffer_ptr, TracyLine) = name.utf8_str(&TracyConcat(_hx_tracy_str_buffer, TracyLine), false, &TracyConcat(_hx_tracy_str_length, TracyLine)); \ | ||
::tracy::ScopedZone TracyConcat(_hx_tracy_scoped_zone,TracyLine)(_hx_stackframe.lineNumber, _hx_stackframe.position->fileName, strlen(_hx_stackframe.position->fileName), _hx_stackframe.position->fullName, strlen(_hx_stackframe.position->fullName), TracyConcat(_hx_tracy_str_buffer_ptr, TracyLine), TracyConcat(_hx_tracy_str_length, TracyLine), __hxcpp_tracy_get_zone_count()); | ||
#else | ||
#define HXCPP_TRACY_ZONE(name) \ | ||
::hx::strbuf TracyConcat(_hx_tracy_str_buffer, TracyLine); \ | ||
int TracyConcat(_hx_tracy_str_length, TracyLine); \ | ||
const char *TracyConcat(_hx_tracy_str_buffer_ptr, TracyLine) = name.utf8_str(&TracyConcat(_hx_tracy_str_buffer, TracyLine), false, &TracyConcat(_hx_tracy_str_length, TracyLine)); \ | ||
::tracy::ScopedZone TracyConcat(_hx_tracy_scoped_zone,TracyLine)(_hx_stackframe.lineNumber, _hx_stackframe.position->fileName, strlen(_hx_stackframe.position->fileName), _hx_stackframe.position->fullName, strlen(_hx_stackframe.position->fullName), TracyConcat(_hx_tracy_str_buffer_ptr, TracyLine), TracyConcat(_hx_tracy_str_length, TracyLine)); | ||
#endif | ||
|
||
void __hxcpp_tracy_framemark(); | ||
void __hxcpp_tracy_plot(::String name, ::Float val); | ||
void __hxcpp_tracy_plot_config(::String name, uint8_t format, bool step, bool fill, int color); | ||
void __hxcpp_tracy_message(::String msg, int color); | ||
void __hxcpp_tracy_message_app_info(::String info); | ||
void __hxcpp_tracy_set_thread_name_and_group(String name, int groupHint); | ||
int __hxcpp_tracy_get_zone_count(); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
|
||
## How to use | ||
|
||
To activate the tracy integration, compile your app with: | ||
|
||
``` | ||
-D HXCPP_TRACY | ||
-D HXCPP_TELEMETRY | ||
-D HXCPP_STACK_TRACE | ||
-D HXCPP_STACK_LINE | ||
``` | ||
|
||
and use the following call in your mainloop: | ||
|
||
``` | ||
cpp.vm.tracy.TracyProfiler.frameMark(); | ||
``` | ||
|
||
Then start either Tracy's UI-App or cmdline server listening on localhost and start your hxcpp-made binary. | ||
|
||
|
||
## Some notes about the integration | ||
|
||
### Haxe-Code | ||
We integrate Tracy into hxcpp as a Telemetry option which utilizes `hx::StackPosition` and offer a set of static functions to set zones and other tracy functionality. Through this all your haxe-code will be captured in a profiler-session. | ||
|
||
There are however native parts of hxcpp that wont be visible by default in Tracy (bc there are no ZoneScopes). | ||
|
||
> Note: Exceptions are in a few spots in the GC-Code, so GC becomes visible for us. | ||
> Note: Hxcpp's native calls will become visible if you use the option to capture callstacks. | ||
> Note: We capture source-locations and their filepaths. By default these are relative to your project and thus the sourcecode preview / browsing in Tracy wont work since it expects absolute paths. To solve this you can use `-D absolute-path` in your builds. | ||
### externs | ||
The same is true about externs you might be using in your project. If you want to make these visible, you need to `@:include('hx/TelemetryTracy.h')` and you gain access to Tracy's C-Macros that you can use in your extern's c/cpp-code. Please refer to the official Tracy documentation: https://github.com/wolfpld/tracy/releases/latest/download/tracy.pdf | ||
|
||
### externs with static/dynamic libs | ||
Another special case are static or dynamic libs your externs might be using. For these you will have to make more changes that are beyond the scope of this doc here, please refer to Tracy's official documentation over here: https://github.com/wolfpld/tracy/releases/latest/download/tracy.pdf | ||
|
||
## Optional Features | ||
|
||
### Memory Profiling | ||
|
||
The following define adds tracking (de-)allocations of hxcpp's small & large object heap. | ||
|
||
``` | ||
-D HXCPP_TRACY_MEMORY | ||
``` | ||
|
||
### Capture Callstacks | ||
|
||
By default we only track zones. If you wanna inspect the actual callstack per zone, you should use the following define: | ||
|
||
``` | ||
-D HXCPP_TRACY_INCLUDE_CALLSTACKS | ||
``` | ||
|
||
> Note: This will inflate the telemetry data A LOT and cost more performance. Please be aware. | ||
|
||
### On Demand Profiling | ||
|
||
By default this integration will start sampling & collecting telemetry with the start of your application. You can change this behavior by the following define and your app will only generate telemetry if the Tracy Profiler app is open and reachable. | ||
|
||
``` | ||
-D HXCPP_TRACY_ON_DEMAND | ||
``` | ||
|
||
### Short-lived Application Support | ||
|
||
In cases where you dont have a mainloop or a very short-lived application you can use the following define to let your application stay around to complete sending telemetry data it has collected. | ||
|
||
``` | ||
-D HXCPP_TRACY_NO_EXIT | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// | ||
// Tracy profiler | ||
// ---------------- | ||
// | ||
// For fast integration, compile and | ||
// link with this source file (and none | ||
// other) in your executable (or in the | ||
// main DLL / shared object on multi-DLL | ||
// projects). | ||
// | ||
|
||
// Define TRACY_ENABLE to enable profiler. | ||
|
||
#include "common/TracySystem.cpp" | ||
|
||
#ifdef TRACY_ENABLE | ||
|
||
#ifdef _MSC_VER | ||
# pragma warning(push, 0) | ||
#endif | ||
|
||
#include "common/tracy_lz4.cpp" | ||
#include "client/TracyProfiler.cpp" | ||
#include "client/TracyCallstack.cpp" | ||
#include "client/TracySysPower.cpp" | ||
#include "client/TracySysTime.cpp" | ||
#include "client/TracySysTrace.cpp" | ||
#include "common/TracySocket.cpp" | ||
#include "client/tracy_rpmalloc.cpp" | ||
#include "client/TracyDxt1.cpp" | ||
#include "client/TracyAlloc.cpp" | ||
#include "client/TracyOverride.cpp" | ||
#include "client/TracyKCore.cpp" | ||
|
||
#if defined(TRACY_HAS_CALLSTACK) | ||
# if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6 | ||
# include "libbacktrace/alloc.cpp" | ||
# include "libbacktrace/dwarf.cpp" | ||
# include "libbacktrace/fileline.cpp" | ||
# include "libbacktrace/mmapio.cpp" | ||
# include "libbacktrace/posix.cpp" | ||
# include "libbacktrace/sort.cpp" | ||
# include "libbacktrace/state.cpp" | ||
# if TRACY_HAS_CALLSTACK == 4 | ||
# include "libbacktrace/macho.cpp" | ||
# else | ||
# include "libbacktrace/elf.cpp" | ||
# endif | ||
# include "common/TracyStackFrames.cpp" | ||
# endif | ||
#endif | ||
|
||
#ifdef _MSC_VER | ||
# pragma comment(lib, "ws2_32.lib") | ||
# pragma comment(lib, "dbghelp.lib") | ||
# pragma comment(lib, "advapi32.lib") | ||
# pragma comment(lib, "user32.lib") | ||
# pragma warning(pop) | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#include "../common/TracyAlloc.hpp" | ||
|
||
#ifdef TRACY_USE_RPMALLOC | ||
|
||
#include <atomic> | ||
|
||
#include "../common/TracyForceInline.hpp" | ||
#include "../common/TracyYield.hpp" | ||
|
||
namespace tracy | ||
{ | ||
|
||
extern thread_local bool RpThreadInitDone; | ||
extern std::atomic<int> RpInitDone; | ||
extern std::atomic<int> RpInitLock; | ||
|
||
tracy_no_inline static void InitRpmallocPlumbing() | ||
{ | ||
const auto done = RpInitDone.load( std::memory_order_acquire ); | ||
if( !done ) | ||
{ | ||
int expected = 0; | ||
while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) ) { expected = 0; YieldThread(); } | ||
const auto done = RpInitDone.load( std::memory_order_acquire ); | ||
if( !done ) | ||
{ | ||
rpmalloc_initialize(); | ||
RpInitDone.store( 1, std::memory_order_release ); | ||
} | ||
RpInitLock.store( 0, std::memory_order_release ); | ||
} | ||
rpmalloc_thread_initialize(); | ||
RpThreadInitDone = true; | ||
} | ||
|
||
TRACY_API void InitRpmalloc() | ||
{ | ||
if( !RpThreadInitDone ) InitRpmallocPlumbing(); | ||
} | ||
|
||
} | ||
|
||
#endif |
Oops, something went wrong.