2,261 Commits over 580 Days - 0.16cph!
Update: PoolAnalyzer - check finally and using blocks
- debug binary built from b28334fc
Down to 48 potentially false-positive errors
Tests: unit tests + started unity
Update: PoolAnalyzer - more escape cases
- recursively process expression statements to detect deeply nested escape cases
- add support for field initializer escapes
- debug binary built from e61378eb
Currently detecting 54 errors (still a bunch of false-positives present)
Tests: unit tests + started unity
Update: PoolAnalyzer - escape analysis if assigned to a variable as part of method arg list
- debug binary build from 8b392070
Currently seeing 60 errors in C+S (3 valid, 2 false-positives, rest unknown).
Tests: unit tests + launched unity
Update: PoolAnalyzer - handle more valid cases
- added support for Dispose handling
- added if(obj != null) Free(ref obj) handling
- added support for using directives (both scoped and inline)
I give up on trying to handle local data flow involving pooled objects - there's just too much work here
Tests: unit tests + started unity (our Pooling unit tests no longer flag false-positives, this was kind of funny)
Update: PoolAnalyzer - escape a bit more
- don't analyze statements before Pool.Get call
- escape analysis when pooled object is returned out of method
- debug binary built from b8b556ae
Tests: unit tests + started unity. still a bunch of false-positives, but found first legit bug
New: PoolAnalyzer - validates code around Pool usage
- debug assembly built from e7281f13
Tests: detected errors, but those are false-positives (return of pooled object instance)
Merge: from save_leak_fix
- Bugfix for items leaking during save - items would be incorrectly marked as persistent when owned by transient entities
Tests: 5 save-load cycles on 2.5k procgen in editor. still leaked ~10 entities per save, but couldn't find them
Bugfix: prevent leaking entities into save from transient containers
Tests: 2.5k procgen map with disabled deep sea - 5 time save-load, went from 15,565 to 15,606. So we're still leaking, but less than a 0.1% per save. Didn't see anything specific in the entity dump.
Update: ServerProfiler.Core - more method annotation exclusions
- release bins built from c969bbab
Mostly focused on reducing the overhead of Scientists2's FSM evaluation and getting rid of injected Burst codegen gunk
Tests: craggy in C+S editor, entered deep sea, went to ghostship to wake up scientists, took a snapshot
Bugfix: handle similar-to-inf budget timespans
Tests: spawned on Craggy - no exceptions
Buildfix: remove non-existent call
Tests: none, trivial change
Clean: remove extra level of indentation
Tests: compiles
Update: InvokeProfiler now pushes executed_time and invokes_executed
Tests: compiles
Update(breaking-change): WorkQueueProfiler now also reports BudgetTime
- breaking as this doesn't match CSV template
Tests: none, compiles
Update: WorkQueueProfiler now sends an extra aggregate record for queues
We could aggregate it on the backend, but that would mean sending through potentially a hefty amount of empty records
Tests: compiles
Clean: add a couple TODOs for when I'll be going through old analytics code cleanup
Tests: none, trivial changes
Update: extracted PersistentObjectWorkQueue.TelemStats into WorkQueueTelemStats
- made ObjectWorkQueue populate it
- every queue now always logs it's budget time, even if it has no work to run (so that we can estimate budgetted/total time %)
Opens it up for use in custom queues as well, but I'll cross that bridge later
Tests: compiles
Bugfix: ensure Runtime profiler reports WorkQueue and Invokes from the same frame
- moved it's logic to be invoked via PostUpdateHook.OnLateUpdate, rather than slamming it directly into PostUpdatehook internals
Previously invokes would be from last frame, while work queues would be from current. It's still a little wrong, as we're reporting it as data from last frame - but at least it's consistently wrong
Tests: none, will deal with any fallout later
Update: rejig a couple parts of TelemStats to simplify code
Tests: compiles
Merge: from leavedeepsea_teleport_fix
- Bugfix: using leavedeepsea should no longer cause random bugs/random wake up positions
Tests: went on to a ghostship, then used leavedeepsea
Bugfix: unparent player if running leavedeepsea
This fixes player waking up in random location, potentially being killed for going out of bounds
Tests: on Craggy, went up to ghostship top and used leavedeepsea couple times
Merge: from serverprofiler_codeapi
- New: immediate mode profiling API for capturing specific regions of code. servervars to control it in "profile" group
- Unit tests covering all new logic
Tests: compile test + ran unit tests
Update: update ServerProfiler.Core bins to Release
- built on 2a311df
Tests: ran all server profiler unit tests
Update: add profile.ImmediateModeEnabled feature flag
- codegen + unit test
Turns off all managed-side logic for new API
Tests: ran unit tests
Update: introduce export interval (profile.ExportIntervalS, defaults to 30m) + ability to reset the interval (profile.ResetExportInterval)
- codegen and extra unit tests
Tests: unit tests
Bugfix: ProfileExporter.JSON can now export 0-frame main thread profiles
Test: ran previously failing unit tests, checked their exported files - all's gud
Update: immediate mode API improvements
- debug windows binary built from 2a311dfb
- ScopeRecorder automatically exports to json and cleans up recorder state
- added RecordScopeIfSlow(..., TimeSpan, ...) API, same as above except exports only if there was a delay
- updated unit tests since some scenarios are now impossible
Need to fix export next, wrap it with a couple server vars and update to release bins - then it's done
Tests: ran most of the unit tests (stress tests skipped as they would overflow with export tasks)
Update: ServerProfiler.Core - various improvements and fixes
- debug windows binary from f50b4fc9
- change internal constants to be more sensible (assumed worker thread count 4 -> 32, max recorders 64 -> 16, max alloc 1GB -> 512MB)
- bugfix for not cleaning up dead thread state when running immediate mode recording
- MemoryPool no longer allocates from heap as a fallback when it's over capacity
Think core lib is done enough for now, gonna move to finishing rust side
Tests: ran unit tests
Update: add TextContextExhaustionTest
- reduce TestDeferCleanup internal loop count to 8 from 16 (as was still possible to starve the pool)
Tests: ran unit tests, pass (got local unsubmitte fixes)
Update: add TestDeferCleanup test
Works, but discovered that I forgot to clean up threads in ServerProfiler.Core, so I'm starving out the pool
Tests: ran new test
Update: minor changes
- MakeScopeRecording -> RecordScope
- fail starting to record if profiler isn't initialized
Tests: unit tests
Update: ServerProfiler.Core - MemoryReadings are now implemented via MemoryPool
- debug windows bins from 47635f61
- ABI break for MemoryData
Tests: unit tests + 10x of StressTestImmediateCaptureMT
Update: ServerProfiler.Core - use memory pooling
- debug windows binary built from af80ca2c
- this fixes/reduces occurance of the MT race
- also reduces capture overhead (at least in debug, 2.2s -> 0.75ms)
- added MPMCQueue license file
Need to revive support for MemoryReadings, will do that next.
Tests: unit tests + StressTestImmediateCaptureMT 10 times
Update: ServerProfiler.Core - replaced my own MPSC queue with a third-party MPMC queue
- debug windows binary from 268ce0c3
Needed to add memory pooling, my own version couldn't handle non-integral types
Tests: unit tests
Update: add StressTestImmediateCaptureMT test
It smashes the profiler from all 20 threads doing allocations and calling methods, while main tries to record just 1 method in a loop. This triggers heap corruption - think allocation pooling would solve this.
Tests: ran extra unit test - it failed drastically
Bugfix: kind-of-fix the thread race with Immediate Mode API (late profiler callback might be in progress as we're releasing resources, leading to invalid write)
- built debug binaries from a3312fa9
- Added a mini stress test for main thread only, needs multithreading to fully validate
I need to optimize internals a bit, to avoid allocation overhead
Tests: ran unit tests on repeat 10 times - no issues
Update: first working version of immediate capture API
- binaries built from b3a39bd2 commit
Has a bug with a race, will fix next
Tests: passes unit tests
Update: blockout Immediate-Record API
- Added unit tests to validate usage
Tests: ran unit tests, has expected failures
Merge: from playerinventory_oncycle_optim
- Bugfix for leaking onCycle items when calling Item::Remove
Tests: unit tests + cooked meat, consumed, cooked again
Bugfix: fix leaking onCycle items when calling Item::Remove
- Consolidated onCycle callback cleanup to DoRemove
- ItemManager::DoRemoves(bool) can now force remove all items
- Added a unit test to validate the logc
Tests: ran unit test, cooked meat on a campfire, ate it, cooked again - no exception
Merge: from useplayertasks_removegroupocludee_nre
- Bugfix for an edge case of moving players during load of a save
Tests: ran unit tests
Bugfix: OcclusionGroup - account for server loading a save potentially recalculating network group
- added a unit test to stress this scenario
Seems like a weird edge case, but it means we gotta work around it
Tests: ran unit tests
Merge: from playerinventory_oncycle_optim
- Buildfix for client
Tests: none, trivial change
Buildfix: add SERVER guards
Tests: none, trivial change
Merge: from playerinventory_oncycle_optim
- Bugfix for exception of duplicate key when loading container with cookables
Tests: unit tests