-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Instrumented instruction #7212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
youknowone
merged 9 commits into
RustPython:main
from
youknowone:instrumented-instruction
Feb 27, 2026
Merged
Instrumented instruction #7212
Changes from 1 commit
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
abc7d6d
Update test_monitoring from CPython 3.14.3
f35d0fd
patch test_monitoring not to entirely skipped
youknowone 739f92e
impl sys.monitoring
youknowone 3c7b25d
Update test_compile from v3.14.3
4ef1b48
instrumented instructions
youknowone 9c329bd
Implement side-table instrumented opcode execution
youknowone fa1e75a
mark failing tests
youknowone 20a93c5
set_f_lineno, set_f_lasti, PyAtomic refactor
youknowone 4567c68
Unmark successful tests
youknowone File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Implement side-table instrumented opcode execution
Add CoMonitoringData with line_opcodes and per_instruction_opcodes side-tables. INSTRUMENTED_LINE and INSTRUMENTED_INSTRUCTION read original opcodes from side-tables and re-dispatch after firing events. - Add decode_exception_table() and CodeUnits::replace_op() - Add Instruction::to_instrumented/to_base/is_instrumented mappings - Three-phase instrument_code: de-instrument, re-instrument regular, then layer INSTRUCTION and LINE with side-table storage - Mark exception handler targets as line starts in LINE placement - InstrumentedLine resolves side-table chain atomically when wrapping InstrumentedInstruction - InstrumentedForIter fires both BRANCH_LEFT and BRANCH_RIGHT - Remove callback on DISABLE return for non-local events
- Loading branch information
commit 9c329bd62f734269c1f564cf503ad626731f2300
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -419,6 +419,100 @@ impl TryFrom<u8> for Instruction { | |
| } | ||
| } | ||
|
|
||
| impl Instruction { | ||
| /// Returns `true` if this is any instrumented opcode | ||
| /// (regular INSTRUMENTED_*, INSTRUMENTED_LINE, or INSTRUMENTED_INSTRUCTION). | ||
| pub fn is_instrumented(self) -> bool { | ||
| self.to_base().is_some() | ||
| || matches!(self, Self::InstrumentedLine | Self::InstrumentedInstruction) | ||
| } | ||
|
|
||
| /// Map a base opcode to its INSTRUMENTED_* variant. | ||
| /// Returns `None` if this opcode has no instrumented counterpart. | ||
| /// | ||
| /// # Panics (debug) | ||
| /// Panics if called on an already-instrumented opcode. | ||
| pub fn to_instrumented(self) -> Option<Self> { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| debug_assert!( | ||
| self.to_base().is_none(), | ||
| "to_instrumented called on already-instrumented opcode {self:?}" | ||
| ); | ||
| Some(match self { | ||
| Self::Resume { .. } => Self::InstrumentedResume, | ||
| Self::ReturnValue => Self::InstrumentedReturnValue, | ||
| Self::YieldValue { .. } => Self::InstrumentedYieldValue, | ||
| Self::Call { .. } => Self::InstrumentedCall, | ||
| Self::CallKw { .. } => Self::InstrumentedCallKw, | ||
| Self::CallFunctionEx => Self::InstrumentedCallFunctionEx, | ||
| Self::LoadSuperAttr { .. } => Self::InstrumentedLoadSuperAttr, | ||
| Self::JumpForward { .. } => Self::InstrumentedJumpForward, | ||
| Self::JumpBackward { .. } => Self::InstrumentedJumpBackward, | ||
| Self::ForIter { .. } => Self::InstrumentedForIter, | ||
| Self::EndFor => Self::InstrumentedEndFor, | ||
| Self::EndSend => Self::InstrumentedEndSend, | ||
| Self::PopJumpIfTrue { .. } => Self::InstrumentedPopJumpIfTrue, | ||
| Self::PopJumpIfFalse { .. } => Self::InstrumentedPopJumpIfFalse, | ||
| Self::PopJumpIfNone { .. } => Self::InstrumentedPopJumpIfNone, | ||
| Self::PopJumpIfNotNone { .. } => Self::InstrumentedPopJumpIfNotNone, | ||
| Self::NotTaken => Self::InstrumentedNotTaken, | ||
| Self::PopIter => Self::InstrumentedPopIter, | ||
| Self::EndAsyncFor => Self::InstrumentedEndAsyncFor, | ||
| _ => return None, | ||
| }) | ||
| } | ||
|
|
||
| /// Map an INSTRUMENTED_* opcode back to its base variant. | ||
| /// Returns `None` if this is not an instrumented opcode. | ||
| /// | ||
| /// The returned base opcode uses `Arg::marker()` for typed fields — | ||
| /// only the opcode byte matters since `replace_op` preserves the arg byte. | ||
| /// | ||
| /// # Panics (debug) | ||
| /// Panics if called on a base opcode that has an instrumented counterpart. | ||
| pub fn to_base(self) -> Option<Self> { | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| Some(match self { | ||
| Self::InstrumentedResume => Self::Resume { arg: Arg::marker() }, | ||
| Self::InstrumentedReturnValue => Self::ReturnValue, | ||
| Self::InstrumentedYieldValue => Self::YieldValue { arg: Arg::marker() }, | ||
| Self::InstrumentedCall => Self::Call { | ||
| nargs: Arg::marker(), | ||
| }, | ||
| Self::InstrumentedCallKw => Self::CallKw { | ||
| nargs: Arg::marker(), | ||
| }, | ||
| Self::InstrumentedCallFunctionEx => Self::CallFunctionEx, | ||
| Self::InstrumentedLoadSuperAttr => Self::LoadSuperAttr { arg: Arg::marker() }, | ||
| Self::InstrumentedJumpForward => Self::JumpForward { | ||
| target: Arg::marker(), | ||
| }, | ||
| Self::InstrumentedJumpBackward => Self::JumpBackward { | ||
| target: Arg::marker(), | ||
| }, | ||
| Self::InstrumentedForIter => Self::ForIter { | ||
| target: Arg::marker(), | ||
| }, | ||
| Self::InstrumentedEndFor => Self::EndFor, | ||
| Self::InstrumentedEndSend => Self::EndSend, | ||
| Self::InstrumentedPopJumpIfTrue => Self::PopJumpIfTrue { | ||
| target: Arg::marker(), | ||
| }, | ||
| Self::InstrumentedPopJumpIfFalse => Self::PopJumpIfFalse { | ||
| target: Arg::marker(), | ||
| }, | ||
| Self::InstrumentedPopJumpIfNone => Self::PopJumpIfNone { | ||
| target: Arg::marker(), | ||
| }, | ||
| Self::InstrumentedPopJumpIfNotNone => Self::PopJumpIfNotNone { | ||
| target: Arg::marker(), | ||
| }, | ||
| Self::InstrumentedNotTaken => Self::NotTaken, | ||
| Self::InstrumentedPopIter => Self::PopIter, | ||
| Self::InstrumentedEndAsyncFor => Self::EndAsyncFor, | ||
| _ => return None, | ||
| }) | ||
| } | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| impl InstructionMetadata for Instruction { | ||
| #[inline] | ||
| fn label_arg(&self) -> Option<Arg<Label>> { | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.