-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
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
GH-108976. Keep monitoring data structures valid during de-optimization during callback. #109131
GH-108976. Keep monitoring data structures valid during de-optimization during callback. #109131
Conversation
…mization in the middle of executing instrumented instructions
@gaogaotiantian I've copied the tests from #109043 This PR does three things:
|
Ah, I knew there should be a better place to fix the code, just did not know where. Yeah putting it in I do think Feel free to close my PR when this is merged :) |
@@ -458,6 +434,9 @@ dump_instrumentation_data(PyCodeObject *code, int star, FILE*out) | |||
static bool | |||
valid_opcode(int opcode) | |||
{ | |||
if (opcode == INSTRUMENTED_LINE) { | |||
return true; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to make the generator add INSTRUMENTED_LINE to _PyOpcode_opcode_metadata
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be, but this PR needs backporting to 3.12 and it's already quite large for a backport this late in the release cycle.
@@ -642,10 +633,11 @@ de_instrument_per_instruction(PyCodeObject *code, int i) | |||
int original_opcode = code->_co_monitoring->per_instruction_opcodes[i]; | |||
CHECK(original_opcode != 0); | |||
CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]); | |||
instr->op.code = original_opcode; | |||
*opcode_ptr = original_opcode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to do this through a pointer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we have INSTRUMENTED_LINE -> INSTRUMENTED_INSTRUCTION -> NORMAL_OPCODE
,
then we want to change the original_opcode
for INSTRUMENTED_LINE
, not the original instruction.
That way we end up with INSTRUMENTED_LINE -> NORMAL_OPCODE
, not just NORMAL_OPCODE
.
This fixes #109156 as well, I think.
@@ -1216,7 +1208,9 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, | |||
} | |||
} while (tools); | |||
Py_DECREF(line_obj); | |||
uint8_t original_opcode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not inline the declaration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because C doesn't allow a declaration immediately following a label.
For arcane historical reasons, probably.
Thanks @markshannon for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12. |
Sorry, @markshannon, I could not cleanly backport this to |
…mization during callback. (pythonGH-109131)
GH-109268 is a backport of this pull request to the 3.12 branch. |
@@ -642,10 +633,11 @@ de_instrument_per_instruction(PyCodeObject *code, int i) | |||
int original_opcode = code->_co_monitoring->per_instruction_opcodes[i]; | |||
CHECK(original_opcode != 0); | |||
CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]); | |||
instr->op.code = original_opcode; | |||
*opcode_ptr = original_opcode; | |||
if (_PyOpcode_Caches[original_opcode]) { | |||
instr[1].cache = adaptive_counter_warmup(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cache would be initialized here even if the instr is INSTRUMENTED_LINE
(but the original_opcode
is an instruction with cache). I guess that's no harm?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is indeed harmless.
Co-authored-by: Tian Gao gaogaotiantian@hotmail.com