diff --git a/src/hx/TelemetryTracy.cpp b/src/hx/TelemetryTracy.cpp index 224a8269f..30c066c40 100644 --- a/src/hx/TelemetryTracy.cpp +++ b/src/hx/TelemetryTracy.cpp @@ -31,9 +31,10 @@ namespace hx { public: std::vector tracyZones; - hx::QuickVec allocs; + hx::QuickVec smallAllocs; + hx::QuickVec largeAllocs; - Telemetry() : tracyZones(0), allocs() {} + Telemetry() : tracyZones(0), smallAllocs(), largeAllocs() {} }; } @@ -65,16 +66,29 @@ void __hxt_gc_new(hx::StackContext* stack, void* obj, int inSize, const char* na void __hxt_gc_alloc(void* obj, int inSize) { + auto stack = hx::StackContext::getCurrent(); + if (isLargeObject(obj)) { + // Skip multiple large object allocations since they can be recycled in-between GC collections. + for (auto i = 0; i < stack->mTelemetry->largeAllocs.size(); i++) + { + if (stack->mTelemetry->largeAllocs[i] == obj) + { + return; + } + } + + stack->mTelemetry->largeAllocs.push(obj); + TracyAllocN(obj, inSize, lohName); } else { + stack->mTelemetry->smallAllocs.push(obj); + TracyAllocN(obj, inSize, sohName); } - - hx::StackContext::getCurrent()->mTelemetry->allocs.push(obj); } void __hxt_gc_realloc(void* oldObj, void* newObj, int newSize) { } @@ -83,32 +97,42 @@ void __hxt_gc_after_mark(int byteMarkId, int endianByteMarkId) { for (auto&& telemetry : created) { - hx::QuickVec retained; + hx::QuickVec smallRetained; + hx::QuickVec largeRetained; + + smallRetained.safeReserveExtra(telemetry->smallAllocs.size()); + largeRetained.safeReserveExtra(telemetry->largeAllocs.size()); - retained.safeReserveExtra(telemetry->allocs.size()); + for (auto i = 0; i < telemetry->smallAllocs.size(); i++) + { + auto ptr = telemetry->smallAllocs[i]; + auto markByte = reinterpret_cast(ptr)[endianByteMarkId]; + if (markByte != byteMarkId) + { + TracyFreeN(ptr, sohName); + } + else + { + smallRetained.push(ptr); + } + } - for (auto i = 0; i < telemetry->allocs.size(); i++) + for (auto i = 0; i < telemetry->largeAllocs.size(); i++) { - auto ptr = telemetry->allocs[i]; + auto ptr = telemetry->largeAllocs[i]; auto markByte = reinterpret_cast(ptr)[endianByteMarkId]; if (markByte != byteMarkId) { - if (isLargeObject(ptr)) - { - TracyFreeN(ptr, lohName); - } - else - { - TracyFreeN(ptr, sohName); - } + TracyFreeN(ptr, lohName); } else { - retained.push(ptr); + largeRetained.push(ptr); } } - telemetry->allocs.swap(retained); + telemetry->smallAllocs.swap(smallRetained); + telemetry->largeAllocs.swap(largeRetained); } }