Skip to content

Commit f054131

Browse files
authored
ZJIT: Add patch_point_count stat (#15100)
1 parent 3ddb5f9 commit f054131

File tree

3 files changed

+44
-19
lines changed

3 files changed

+44
-19
lines changed

zjit.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ def stats_string
191191
:dynamic_getivar_count,
192192
:dynamic_setivar_count,
193193

194+
:patch_point_count,
194195
:compiled_iseq_count,
195196
:failed_iseq_count,
196197

zjit/src/invariants.rs

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
33
use std::{collections::{HashMap, HashSet}, mem};
44

5-
use crate::{backend::lir::{asm_comment, Assembler}, cruby::{iseq_name, rb_callable_method_entry_t, rb_gc_location, ruby_basic_operators, src_loc, with_vm_lock, IseqPtr, RedefinitionFlag, ID, VALUE}, hir::Invariant, options::debug, state::{zjit_enabled_p, ZJITState}, virtualmem::CodePtr};
5+
use crate::{backend::lir::{Assembler, asm_comment}, cast::IntoU64, cruby::{ID, IseqPtr, RedefinitionFlag, VALUE, iseq_name, rb_callable_method_entry_t, rb_gc_location, ruby_basic_operators, src_loc, with_vm_lock}, hir::Invariant, options::debug, state::{ZJITState, zjit_enabled_p}, stats::{decr_counter_by, incr_counter}, virtualmem::CodePtr};
66
use crate::payload::IseqPayload;
77
use crate::stats::with_time_stat;
8-
use crate::stats::Counter::invalidation_time_ns;
8+
use crate::stats::Counter::{invalidation_time_ns, patch_point_count};
99
use crate::gc::remove_gc_offsets;
1010

1111
macro_rules! compile_patch_points {
@@ -36,6 +36,23 @@ struct PatchPoint {
3636
payload_ptr: *mut IseqPayload,
3737
}
3838

39+
impl PatchPoint {
40+
/// PatchPointer constructor, which also increments `patch_point_count`
41+
fn new(patch_point_ptr: CodePtr, side_exit_ptr: CodePtr, payload_ptr: *mut IseqPayload) -> PatchPoint {
42+
incr_counter!(patch_point_count);
43+
Self {
44+
patch_point_ptr,
45+
side_exit_ptr,
46+
payload_ptr,
47+
}
48+
}
49+
50+
/// Decrease `patch_point_count` by the size of a given `HashSet<PatchPoint>`
51+
fn decr_counter(patch_points: HashSet<PatchPoint>) {
52+
decr_counter_by(patch_point_count, patch_points.len().as_u64());
53+
}
54+
}
55+
3956
/// Used to track all of the various block references that contain assumptions
4057
/// about the state of the virtual machine.
4158
#[derive(Default)]
@@ -83,17 +100,17 @@ impl Invariants {
83100
// generated code referencing the ISEQ are unreachable. We mark the ISEQs baked into
84101
// generated code.
85102
self.ep_escape_iseqs.remove(&iseq);
86-
self.no_ep_escape_iseq_patch_points.remove(&iseq);
103+
self.no_ep_escape_iseq_patch_points.remove(&iseq).map(PatchPoint::decr_counter);
87104
}
88105

89106
/// Forget a CME when freeing it. See [Self::forget_iseq] for reasoning.
90107
pub fn forget_cme(&mut self, cme: *const rb_callable_method_entry_t) {
91-
self.cme_patch_points.remove(&cme);
108+
self.cme_patch_points.remove(&cme).map(PatchPoint::decr_counter);
92109
}
93110

94111
/// Forget a class when freeing it. See [Self::forget_iseq] for reasoning.
95112
pub fn forget_klass(&mut self, klass: VALUE) {
96-
self.no_singleton_class_patch_points.remove(&klass);
113+
self.no_singleton_class_patch_points.remove(&klass).map(PatchPoint::decr_counter);
97114
}
98115

99116
/// Update ISEQ references in Invariants::ep_escape_iseqs
@@ -198,11 +215,11 @@ pub fn track_no_ep_escape_assumption(
198215
payload_ptr: *mut IseqPayload,
199216
) {
200217
let invariants = ZJITState::get_invariants();
201-
invariants.no_ep_escape_iseq_patch_points.entry(iseq).or_default().insert(PatchPoint {
218+
invariants.no_ep_escape_iseq_patch_points.entry(iseq).or_default().insert(PatchPoint::new(
202219
patch_point_ptr,
203220
side_exit_ptr,
204221
payload_ptr,
205-
});
222+
));
206223
}
207224

208225
/// Returns true if a given ISEQ has previously escaped environment pointer.
@@ -219,11 +236,11 @@ pub fn track_bop_assumption(
219236
payload_ptr: *mut IseqPayload,
220237
) {
221238
let invariants = ZJITState::get_invariants();
222-
invariants.bop_patch_points.entry((klass, bop)).or_default().insert(PatchPoint {
239+
invariants.bop_patch_points.entry((klass, bop)).or_default().insert(PatchPoint::new(
223240
patch_point_ptr,
224241
side_exit_ptr,
225242
payload_ptr,
226-
});
243+
));
227244
}
228245

229246
/// Track a patch point for a callable method entry (CME).
@@ -234,11 +251,11 @@ pub fn track_cme_assumption(
234251
payload_ptr: *mut IseqPayload,
235252
) {
236253
let invariants = ZJITState::get_invariants();
237-
invariants.cme_patch_points.entry(cme).or_default().insert(PatchPoint {
254+
invariants.cme_patch_points.entry(cme).or_default().insert(PatchPoint::new(
238255
patch_point_ptr,
239256
side_exit_ptr,
240257
payload_ptr,
241-
});
258+
));
242259
}
243260

244261
/// Track a patch point for each constant name in a constant path assumption.
@@ -257,11 +274,11 @@ pub fn track_stable_constant_names_assumption(
257274
break;
258275
}
259276

260-
invariants.constant_state_patch_points.entry(id).or_default().insert(PatchPoint {
277+
invariants.constant_state_patch_points.entry(id).or_default().insert(PatchPoint::new(
261278
patch_point_ptr,
262279
side_exit_ptr,
263280
payload_ptr,
264-
});
281+
));
265282

266283
idx += 1;
267284
}
@@ -275,11 +292,11 @@ pub fn track_no_singleton_class_assumption(
275292
payload_ptr: *mut IseqPayload,
276293
) {
277294
let invariants = ZJITState::get_invariants();
278-
invariants.no_singleton_class_patch_points.entry(klass).or_default().insert(PatchPoint {
295+
invariants.no_singleton_class_patch_points.entry(klass).or_default().insert(PatchPoint::new(
279296
patch_point_ptr,
280297
side_exit_ptr,
281298
payload_ptr,
282-
});
299+
));
283300
}
284301

285302
/// Called when a method is redefined. Invalidates all JIT code that depends on the CME.
@@ -330,11 +347,11 @@ pub extern "C" fn rb_zjit_constant_state_changed(id: ID) {
330347
/// Track the JIT code that assumes that the interpreter is running with only one ractor
331348
pub fn track_single_ractor_assumption(patch_point_ptr: CodePtr, side_exit_ptr: CodePtr, payload_ptr: *mut IseqPayload) {
332349
let invariants = ZJITState::get_invariants();
333-
invariants.single_ractor_patch_points.insert(PatchPoint {
350+
invariants.single_ractor_patch_points.insert(PatchPoint::new(
334351
patch_point_ptr,
335352
side_exit_ptr,
336353
payload_ptr,
337-
});
354+
));
338355
}
339356

340357
/// Callback for when Ruby is about to spawn a ractor. In that case we need to
@@ -359,11 +376,11 @@ pub extern "C" fn rb_zjit_before_ractor_spawn() {
359376

360377
pub fn track_no_trace_point_assumption(patch_point_ptr: CodePtr, side_exit_ptr: CodePtr, payload_ptr: *mut IseqPayload) {
361378
let invariants = ZJITState::get_invariants();
362-
invariants.no_trace_point_patch_points.insert(PatchPoint {
379+
invariants.no_trace_point_patch_points.insert(PatchPoint::new(
363380
patch_point_ptr,
364381
side_exit_ptr,
365382
payload_ptr,
366-
});
383+
));
367384
}
368385

369386
#[unsafe(no_mangle)]

zjit/src/stats.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ macro_rules! make_counters {
114114
make_counters! {
115115
// Default counters that are available without --zjit-stats
116116
default {
117+
patch_point_count,
117118
compiled_iseq_count,
118119
failed_iseq_count,
119120

@@ -307,6 +308,12 @@ pub fn incr_counter_by(counter: Counter, amount: u64) {
307308
unsafe { *ptr += amount; }
308309
}
309310

311+
/// Decrease a counter by a specified amount
312+
pub fn decr_counter_by(counter: Counter, amount: u64) {
313+
let ptr = counter_ptr(counter);
314+
unsafe { *ptr -= amount; }
315+
}
316+
310317
/// Increment a counter by its identifier
311318
macro_rules! incr_counter {
312319
($counter_name:ident) => {

0 commit comments

Comments
 (0)