-
Notifications
You must be signed in to change notification settings - Fork 440
feat(gnovm): VM Instrumentation and Profiling System #4898
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
🛠 PR Checks Summary🔴 Pending initial approval by a review team member, or review from tech-staff Manual Checks (for Reviewers):
Read More🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers. ✅ Automated Checks (for Contributors):🟢 Maintainers must be able to edit this pull request (more info) ☑️ Contributor Actions:
☑️ Reviewer Actions:
📚 Resources:Debug
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Previously, allocation events were emitted without proper call stack
context, making it difficult to attribute memory consumption to actual
source functions. This change ensures allocation profiling captures
the complete execution context at allocation time.
Changes:
* Profiler: RecordAlloc now increments CallCount for allocation events
- Allocation statistics now appear correctly in toplists and call trees
- Functions allocating memory are tracked with proper call counts
- Added TestProfilerRecordAllocUsesCallStack to verify allocations
derive function names, bytes, and object counts from the top frame
rather than synthetic "<allocation>" markers
* Interactive shell: Memory mode toplists now display allocation metrics
- Both flat and cumulative columns show bytes allocated
- Appropriate labels and percentages reflect memory-specific semantics
- Differs from CPU/gas modes where cumulative includes nested calls
* Allocator sink wiring: Introduced allocationStackInjector adapter
- Wraps allocator sinks to capture machine frames when events lack them
- Ensures all memory events inherit real call stacks from VM state
- Added TestAllocationStackInjectorAddsMachineFrames to verify
stack injection behavior
Profiling a package now captures both standard tests and filetests, and momory mode no longer drops data when `MAXALLOC` is unspecified. - Updated filetest codebase to provision machines for profiling: when a memory profile is requested and no `MAXALLOC` is set, we now install an unlimited allocator so allocation events reach the profiler. we also attach the `ProfileConfig` sink to filetest mechaines, putting `*_filetest.gno` executions on par with `_test.gno`. - Added `provisionFiletestAllocator` helper and unit tests in `gnovm/pkg/test/filetest_test.go` to ensure we only create allocators when necessary and leave existing ones untouched.
- Sampling only happend in `OpCall`, missing work in loop/other ops - Move `maybeEmitSample` into `incrCPU` so every opcode can trigger samples - Test: ensure `maybeEmitSample` fires when CPU cycles are incremented (profile sink receives a sample)
Profiling now runs as a single session across gno test package loops, so profile data and the interactive shell cover all packages instead of just the last one. ## Changes - add `Start`/`Stop` lifecycle helpers on `ProfileConfig`. Test now only initializes/finalizes profiling when it owns the session, skipping per-package resets when a session is already active. - `execTest` starts profiling once, ensures cleanup even on early returns, and finalizes before `maybeStartProfileShell` so the shell sees the aggregated profile.
Profiling now carries machine identity through instrumentation, keeps per-machine baselines, attributes allocations into call trees/line stats, and guards against accidental profiler restarts. - add `MachineID` plumbing on samples/allocations/line samples, propagate through adapter/machine with unsafe pointer IDs - per-machine baselines with ensureBaseline/optional Identity, StartProfiling returns early when already active, allocations now flow into call tree and line stats with bytes/objects tracked, call tree export/sorting honors memory profiles, function sorting updated for memory, new helpers for allocation line stats.
Description
This pull request introduces the instrumentation-first profiling architecture. The VM now emits structured events (CPU/gas samples, allocation events, and line samples) through a
instrumentation.Sinkinterface, and the profiler consumes those events without depending on VM internals.docs (draft): https://gist.github.com/notJoon/de3a4e4fceeedd25bddcecef289be547
Key Changes
Instrumentation Layer
instrumentationpackage withSampleContext,FrameSnapshot,AllocationEvent,LineSample, andSink.Machineaccepts an optional sink viaMachineOptions. When nil, the VM runs with zero additional work (only a nil-check).Profiler Core
FrameIDs).Profile.WriteFormat.CLI / Test Harness Integration
ProfileConfigwires sinks into every test VM, enables gas meters or allocators as needed, and exposes new flags:-profilemaster switch.-profile-type,-profile-format,-profile-sample-rate,-profile-output,-profile-stdout.-profile-interactive(launch shell) and-profile-line(enable line-level sampling).pprofcommands (top,list,calltree,json,text,clear,exit), reusing the captured profile without rerunning tests.