File tree Expand file tree Collapse file tree 3 files changed +40
-14
lines changed
Expand file tree Collapse file tree 3 files changed +40
-14
lines changed Original file line number Diff line number Diff line change @@ -560,10 +560,14 @@ impl CodeUnits {
560560 let op = units[ i] . op ;
561561 let caches = op. cache_entries ( ) ;
562562 if caches > 0 {
563- let cache_base = i + 1 ;
564- if cache_base < len {
565- unsafe {
566- self . write_adaptive_counter ( cache_base, ADAPTIVE_WARMUP_VALUE ) ;
563+ // Don't write adaptive counter for instrumented opcodes;
564+ // specialization is skipped while monitoring is active.
565+ if !op. is_instrumented ( ) {
566+ let cache_base = i + 1 ;
567+ if cache_base < len {
568+ unsafe {
569+ self . write_adaptive_counter ( cache_base, ADAPTIVE_WARMUP_VALUE ) ;
570+ }
567571 }
568572 }
569573 i += 1 + caches;
Original file line number Diff line number Diff line change @@ -620,8 +620,11 @@ impl Instruction {
620620 }
621621 // RESUME specializations
622622 Self :: ResumeCheck => Self :: Resume { arg : Arg :: marker ( ) } ,
623- // Everything else maps to itself
624- _ => self ,
623+ // Instrumented opcodes map back to their base
624+ _ => match self . to_base ( ) {
625+ Some ( base) => base,
626+ None => self ,
627+ } ,
625628 }
626629 }
627630
@@ -739,8 +742,11 @@ impl Instruction {
739742 | Self :: UnpackSequenceTuple
740743 | Self :: UnpackSequenceTwoTuple => 1 ,
741744
742- // Everything else: 0 cache entries
743- _ => 0 ,
745+ // Instrumented opcodes have the same cache entries as their base
746+ _ => match self . to_base ( ) {
747+ Some ( base) => base. cache_entries ( ) ,
748+ None => 0 ,
749+ } ,
744750 }
745751 }
746752}
Original file line number Diff line number Diff line change @@ -270,13 +270,29 @@ pub fn instrument_code(code: &PyCode, events: u32) {
270270 }
271271 }
272272
273- // Phase 3: Remove regular INSTRUMENTED_* → restore base opcodes
274- for i in 0 ..len {
275- let op = code. code . instructions [ i] . op ;
276- if let Some ( base) = op. to_base ( ) {
277- unsafe {
278- code. code . instructions . replace_op ( i, base) ;
273+ // Phase 3: Remove regular INSTRUMENTED_* and specialized opcodes → restore base opcodes.
274+ // Also clear all CACHE entries so specialization starts fresh.
275+ {
276+ let mut i = 0 ;
277+ while i < len {
278+ let op = code. code . instructions [ i] . op ;
279+ let de_opt = op. deoptimize ( ) ;
280+ if u8:: from ( de_opt) != u8:: from ( op) {
281+ unsafe {
282+ code. code . instructions . replace_op ( i, de_opt) ;
283+ }
284+ }
285+ let caches = de_opt. cache_entries ( ) ;
286+ // Zero all CACHE entries (the op+arg bytes may have been overwritten
287+ // by specialization with arbitrary data like pointers).
288+ for c in 1 ..=caches {
289+ if i + c < len {
290+ unsafe {
291+ code. code . instructions . write_cache_u16 ( i + c, 0 ) ;
292+ }
293+ }
279294 }
295+ i += 1 + caches;
280296 }
281297 }
282298
You can’t perform that action at this time.
0 commit comments