summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAiden Fox Ivey <aiden.foxivey@shopify.com>2025-09-30 16:51:56 -0400
committerGitHub <noreply@github.com>2025-09-30 20:51:56 +0000
commitdf2d1d5ad386c51ad9750282917ecacf2b343598 (patch)
treeccf3ae1ffb460d6935e6269ef2446537f8189c73
parente90729aa6c34d00743e2de9095293d3189587333 (diff)
ZJIT: Decouple stats and side exit tracing (#14688)
-rw-r--r--doc/zjit.md4
-rw-r--r--zjit.rb8
-rw-r--r--zjit/src/state.rs2
-rw-r--r--zjit/src/stats.rs9
4 files changed, 12 insertions, 11 deletions
diff --git a/doc/zjit.md b/doc/zjit.md
index 57a95457d3..ba65739e3f 100644
--- a/doc/zjit.md
+++ b/doc/zjit.md
@@ -155,10 +155,10 @@ make -j
### Tracing side exits
-Through [Stackprof](https://github.com/tmm1/stackprof), detailed information about the methods that the JIT side-exits from can be displayed after some execution of a program. Note that the use of `--zjit-trace-exits` must be used alongside `--zjit-stats`.
+Through [Stackprof](https://github.com/tmm1/stackprof), detailed information about the methods that the JIT side-exits from can be displayed after some execution of a program.
```bash
-./miniruby --zjit-stats --zjit-trace-exits script.rb
+./miniruby --zjit-trace-exits script.rb
```
A file called `zjit_exit_locations.dump` will be created in the same directory as `script.rb`. Viewing the side exited methods can be done with Stackprof:
diff --git a/zjit.rb b/zjit.rb
index 155f16a713..2ff4cf2a5b 100644
--- a/zjit.rb
+++ b/zjit.rb
@@ -9,10 +9,10 @@
module RubyVM::ZJIT
# Avoid calling a Ruby method here to avoid interfering with compilation tests
if Primitive.rb_zjit_print_stats_p
- at_exit {
- print_stats
- dump_locations
- }
+ at_exit { print_stats }
+ end
+ if Primitive.rb_zjit_trace_exit_locations_enabled_p
+ at_exit { dump_locations }
end
end
diff --git a/zjit/src/state.rs b/zjit/src/state.rs
index 50c3f4b1c1..206a7b3b61 100644
--- a/zjit/src/state.rs
+++ b/zjit/src/state.rs
@@ -392,7 +392,7 @@ pub extern "C" fn rb_zjit_record_exit_stack(exit_pc: *const VALUE) {
/// Mark `raw_samples` so they can be used by rb_zjit_add_frame.
pub fn gc_mark_raw_samples() {
// Return if ZJIT is not enabled
- if !zjit_enabled_p() || !get_option!(stats) || !get_option!(trace_side_exits) {
+ if !zjit_enabled_p() || !get_option!(trace_side_exits) {
return;
}
diff --git a/zjit/src/stats.rs b/zjit/src/stats.rs
index 05ae231dad..a9cf1bde7c 100644
--- a/zjit/src/stats.rs
+++ b/zjit/src/stats.rs
@@ -2,6 +2,7 @@
use std::time::Instant;
use std::sync::atomic::Ordering;
+use crate::options::OPTIONS;
#[cfg(feature = "stats_allocator")]
#[path = "../../jit/src/lib.rs"]
@@ -475,11 +476,11 @@ pub struct SideExitLocations {
/// Primitive called in zjit.rb
///
-/// Check if trace_exits generation is enabled. Requires the stats feature
-/// to be enabled.
+/// Check if trace_exits generation is enabled.
#[unsafe(no_mangle)]
pub extern "C" fn rb_zjit_trace_exit_locations_enabled_p(_ec: EcPtr, _ruby_self: VALUE) -> VALUE {
- if get_option!(stats) && get_option!(trace_side_exits) {
+ // Builtin zjit.rb calls this even if ZJIT is disabled, so OPTIONS may not be set.
+ if unsafe { OPTIONS.as_ref() }.is_some_and(|opts| opts.trace_side_exits) {
Qtrue
} else {
Qfalse
@@ -490,7 +491,7 @@ pub extern "C" fn rb_zjit_trace_exit_locations_enabled_p(_ec: EcPtr, _ruby_self:
/// into raw, lines, and frames hash for RubyVM::YJIT.exit_locations.
#[unsafe(no_mangle)]
pub extern "C" fn rb_zjit_get_exit_locations(_ec: EcPtr, _ruby_self: VALUE) -> VALUE {
- if !zjit_enabled_p() || !get_option!(stats) || !get_option!(trace_side_exits) {
+ if !zjit_enabled_p() || !get_option!(trace_side_exits) {
return Qnil;
}