@@ -55,26 +55,22 @@ def adaptive_counters(self, f):
5555 def assert_specialization_stable (self , f , * args , calls = 10 ):
5656 """Assert that no specialized instruction in f misses its guard.
5757
58- A specialized instruction whose guard holds leaves its adaptive
59- counter untouched. One whose guard fails on every execution
60- (the specializer accepted a site its guard then rejects) advances
61- the counter on each miss, so comparing the counters before and
62- after a few more calls detects the mismatch without needing a
63- pystats build.
64-
65- f must start from a fresh code object (see reset_code()): a nested
66- function reuses its code object across calls of the enclosing test,
67- so a specialization left over from a previous run with different
68- operands would show up here as a miss.
58+ A guard miss advances the instruction's adaptive counter. f should
59+ have a fresh code object (see reset_code()), otherwise leftover
60+ specializations from earlier runs can show up as misses.
6961 """
7062 before = self .adaptive_counters (f )
7163 self .assertTrue (before , f"{ f .__qualname__ } has no specialized "
7264 "instructions" )
7365 for _ in range (calls ):
7466 f (* args )
7567 after = self .adaptive_counters (f )
76- moved = [f"{ op } at offset { off } : counter { before [off ][1 ]} -> { c } "
77- for off , (op , c ) in after .items () if before [off ] != (op , c )]
68+ # Ignore instructions that only specialize during these calls.
69+ moved = []
70+ for off , (op , counter ) in before .items ():
71+ if after .get (off ) != (op , counter ):
72+ now = after [off ][1 ] if off in after else "unspecialized"
73+ moved .append (f"{ op } at offset { off } : counter { counter } -> { now } " )
7874 self .assertEqual (moved , [],
7975 f"specialized instructions in { f .__qualname__ } "
8076 f"missed their guard during { calls } calls" )
@@ -2218,12 +2214,10 @@ class MyList(list): pass
22182214
22192215 @cpython_only
22202216 @requires_specialization
2221- @requires_jit_disabled # JIT-compiled code stops moving tier-1 counters
2217+ @requires_jit_disabled
22222218 def test_call_method_descriptor_subclass_instance (self ):
2223- # A C method inherited from a built-in type is specialized for
2224- # subclass instances too; each guard must accept the subtype
2225- # rather than miss on every call. One case per guard, plus the
2226- # unbound form where the receiver is the first argument.
2219+ # C methods inherited from a built-in type must not miss
2220+ # their guard on subclass instances. One case per guard, plus unbound.
22272221 class MyStr (str ): pass
22282222 Point = collections .namedtuple ("Point" , "x y" )
22292223 counts = collections .defaultdict (int , {1 : 2 })
0 commit comments