(
&mut self,
instruction: Instruction,
arg: bytecode::OpArg,
vm: &VirtualMachine,
)
| 5727 | /// runs when sys.monitoring has rewritten the bytecode. |
| 5728 | #[cold] |
| 5729 | fn execute_instrumented( |
| 5730 | &mut self, |
| 5731 | instruction: Instruction, |
| 5732 | arg: bytecode::OpArg, |
| 5733 | vm: &VirtualMachine, |
| 5734 | ) -> FrameResult { |
| 5735 | debug_assert!( |
| 5736 | instruction.is_instrumented(), |
| 5737 | "execute_instrumented called with non-instrumented opcode {instruction:?}" |
| 5738 | ); |
| 5739 | if self.monitoring_disabled_for_code(vm) { |
| 5740 | let global_ver = vm |
| 5741 | .state |
| 5742 | .instrumentation_version |
| 5743 | .load(atomic::Ordering::Acquire); |
| 5744 | monitoring::instrument_code(self.code, 0); |
| 5745 | self.code |
| 5746 | .instrumentation_version |
| 5747 | .store(global_ver, atomic::Ordering::Release); |
| 5748 | self.update_lasti(|i| *i -= 1); |
| 5749 | return Ok(None); |
| 5750 | } |
| 5751 | self.monitoring_mask = vm.state.monitoring_events.load(); |
| 5752 | match instruction { |
| 5753 | Instruction::InstrumentedResume => { |
| 5754 | // Version check: re-instrument if stale |
| 5755 | let global_ver = vm |
| 5756 | .state |
| 5757 | .instrumentation_version |
| 5758 | .load(atomic::Ordering::Acquire); |
| 5759 | let code_ver = self |
| 5760 | .code |
| 5761 | .instrumentation_version |
| 5762 | .load(atomic::Ordering::Acquire); |
| 5763 | if code_ver != global_ver { |
| 5764 | let events = { |
| 5765 | let state = vm.state.monitoring.lock(); |
| 5766 | state.events_for_code(self.code.get_id()) |
| 5767 | }; |
| 5768 | monitoring::instrument_code(self.code, events); |
| 5769 | self.code |
| 5770 | .instrumentation_version |
| 5771 | .store(global_ver, atomic::Ordering::Release); |
| 5772 | // Re-execute (may have been de-instrumented to base Resume) |
| 5773 | self.update_lasti(|i| *i -= 1); |
| 5774 | return Ok(None); |
| 5775 | } |
| 5776 | let resume_type = u32::from(arg); |
| 5777 | let offset = (self.lasti() - 1) * 2; |
| 5778 | if resume_type == 0 { |
| 5779 | if self.monitoring_mask & monitoring::EVENT_PY_START != 0 { |
| 5780 | monitoring::fire_py_start(vm, self.code, offset)?; |
| 5781 | } |
| 5782 | } else if self.monitoring_mask & monitoring::EVENT_PY_RESUME != 0 { |
| 5783 | monitoring::fire_py_resume(vm, self.code, offset)?; |
| 5784 | } |
| 5785 | Ok(None) |
| 5786 | } |
no test coverage detected