22
33use 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 } ;
66use crate :: payload:: IseqPayload ;
77use crate :: stats:: with_time_stat;
8- use crate :: stats:: Counter :: invalidation_time_ns;
8+ use crate :: stats:: Counter :: { invalidation_time_ns, patch_point_count } ;
99use crate :: gc:: remove_gc_offsets;
1010
1111macro_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
331348pub 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
360377pub 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) ]
0 commit comments