diff options
| author | Takashi Kokubun <takashikkbn@gmail.com> | 2026-03-25 07:49:47 -0700 |
|---|---|---|
| committer | Takashi Kokubun <takashikkbn@gmail.com> | 2026-03-25 13:34:11 -0700 |
| commit | 75a396c6d3d298bcb6079eb40a7d6ae67d7ad5bd (patch) | |
| tree | 80014e879573e7d269a5047080e78484ad8d8c78 /zjit | |
| parent | 7dff7b351e7081936673f4188768111699f5af91 (diff) | |
ZJIT: Count profiles remaining down instead of up
Count down from --zjit-num-profiles to 0 instead of counting up. This
avoids reading options state in done_profiling_at and profile_send_at
at check time. Also simplify the stack offset arithmetic in
profile_send_at: -1 - (n - i - 1) simplifies to (i - n).
Diffstat (limited to 'zjit')
| -rw-r--r-- | zjit/src/profile.rs | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/zjit/src/profile.rs b/zjit/src/profile.rs index fd2ccdeb5f..1ea27dcb45 100644 --- a/zjit/src/profile.rs +++ b/zjit/src/profile.rs @@ -103,10 +103,10 @@ fn profile_insn(bare_opcode: ruby_vminsn_type, ec: EcPtr) { _ => {} } - // Once we profile the instruction num_profiles times, we stop profiling it. + // Once we profile the instruction enough times, we stop profiling it. let entry = profile.entry_mut(profiler.insn_idx); - entry.num_profiles = entry.num_profiles.saturating_add(1); - if entry.num_profiles == get_option!(num_profiles) { + entry.profiles_remaining = entry.profiles_remaining.saturating_sub(1); + if entry.profiles_remaining == 0 { unsafe { rb_zjit_iseq_insn_set(profiler.iseq, profiler.insn_idx as u32, bare_opcode); } } } @@ -382,8 +382,8 @@ struct ProfileEntry { insn_idx: u32, /// Type information of YARV instruction operands opnd_types: Vec<TypeDistribution>, - /// Number of profiled executions for this YARV instruction - num_profiles: NumProfiles, + /// Number of profiles remaining before recompilation. Counts down from --zjit-num-profiles. + profiles_remaining: NumProfiles, } #[derive(Debug)] @@ -413,7 +413,7 @@ impl IseqProfile { self.entries.insert(i, ProfileEntry { insn_idx: idx, opnd_types: Vec::new(), - num_profiles: 0, + profiles_remaining: get_option!(num_profiles), }); &mut self.entries[i] } @@ -427,15 +427,15 @@ impl IseqProfile { .ok().map(|i| &self.entries[i]) } - /// Profile send operands from the stack at runtime. - /// `sp` is the current stack pointer (after the args and receiver). - /// `argc` is the number of arguments (not counting receiver). - /// Returns true if enough profiles have been gathered and the ISEQ should be recompiled. /// Check if enough profiles have been gathered for this instruction. pub fn done_profiling_at(&self, insn_idx: usize) -> bool { - self.entry(insn_idx).map_or(false, |e| e.num_profiles >= get_option!(num_profiles)) + self.entry(insn_idx).map_or(false, |e| e.profiles_remaining == 0) } + /// Profile send operands from the stack at runtime. + /// `sp` is the current stack pointer (after the args and receiver). + /// `argc` is the number of arguments (not counting receiver). + /// Returns true if enough profiles have been gathered and the ISEQ should be recompiled. pub fn profile_send_at(&mut self, iseq: IseqPtr, insn_idx: usize, sp: *const VALUE, argc: usize) -> bool { let n = argc + 1; // args + receiver let entry = self.entry_mut(insn_idx); @@ -443,13 +443,13 @@ impl IseqProfile { entry.opnd_types.resize(n, TypeDistribution::new()); } for i in 0..n { - let obj = unsafe { *sp.offset(-1 - (n - i - 1) as isize) }; + let obj = unsafe { *sp.offset(i as isize - n as isize) }; let ty = ProfiledType::new(obj); VALUE::from(iseq).write_barrier(ty.class()); entry.opnd_types[i].observe(ty); } - entry.num_profiles = entry.num_profiles.saturating_add(1); - entry.num_profiles == get_option!(num_profiles) + entry.profiles_remaining = entry.profiles_remaining.saturating_sub(1); + entry.profiles_remaining == 0 } /// Get profiled operand types for a given instruction index |
