-
-
Notifications
You must be signed in to change notification settings - Fork 32k
gh-109052: Use the base opcode when comparing code objects #109107
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Use the base opcode when comparing code objects to avoid interference from instrumentation |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1797,28 +1797,26 @@ code_richcompare(PyObject *self, PyObject *other, int op) | |
for (int i = 0; i < Py_SIZE(co); i++) { | ||
_Py_CODEUNIT co_instr = _PyCode_CODE(co)[i]; | ||
_Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i]; | ||
uint8_t co_code = co_instr.op.code; | ||
uint8_t co_code = _Py_GetBaseOpcode(co, i); | ||
uint8_t co_arg = co_instr.op.arg; | ||
uint8_t cp_code = cp_instr.op.code; | ||
uint8_t cp_code = _Py_GetBaseOpcode(cp, i); | ||
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. ditto |
||
uint8_t cp_arg = cp_instr.op.arg; | ||
|
||
if (co_code == ENTER_EXECUTOR) { | ||
const int exec_index = co_arg; | ||
_PyExecutorObject *exec = co->co_executors->executors[exec_index]; | ||
co_code = exec->vm_data.opcode; | ||
co_code = _PyOpcode_Deopt[exec->vm_data.opcode]; | ||
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. Nice catch. I think I agree with @gvanrossum though that 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. Yes, I can work on that. 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. So @gvanrossum mentioned we should NOT handle 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. See the list of bullets in gh-107265. |
||
co_arg = exec->vm_data.oparg; | ||
} | ||
assert(co_code != ENTER_EXECUTOR); | ||
co_code = _PyOpcode_Deopt[co_code]; | ||
|
||
if (cp_code == ENTER_EXECUTOR) { | ||
const int exec_index = cp_arg; | ||
_PyExecutorObject *exec = cp->co_executors->executors[exec_index]; | ||
cp_code = exec->vm_data.opcode; | ||
cp_code = _PyOpcode_Deopt[exec->vm_data.opcode]; | ||
cp_arg = exec->vm_data.oparg; | ||
} | ||
assert(cp_code != ENTER_EXECUTOR); | ||
cp_code = _PyOpcode_Deopt[cp_code]; | ||
|
||
if (co_code != cp_code || co_arg != cp_arg) { | ||
goto unequal; | ||
|
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.
I am not sure that calling this API at this moment is correct.
Because it will call _PyOpcode_Deopt twice in the end.
See L1812, what will happen
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.
Or move co_code or cp_code = _PyOpcode_Deopt[cocode or cp_code]; only if cp_code or co_code is ENTER_EXECUTOR at L1805 or L1814
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.
_PyOpcode_Deopt[]
is idempotent, so it is harmless.I think we should change this code to be exactly the same as what
deopt_code()
does, since that's what we're after -- we want to compareco.co_code
tocp.co_code
without creating those objects.I also think that
_Py_GetBaseOpcode()
should mapENTER_EXECUTOR
so we wouldn't have to worry about it here at all.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.
FYI, If we decide to fix
_Py_GetBaseOpcode()
, we can update #107265 toocc @brandtbucher
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.
And maybe we can close #107265 in one short.
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.
IIRC there are also cases where we absolutely want the actual opcode, so in those cases we still need to handle ENTER_EXECUTOR explicitly. But yeah, fixing this in
_Py_GetBaseOpcode()
might reduce the special cases elsewhere. In a new PR, please. :-)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.
IMPORTANT! Do not attempt to "fix"
_Py_GetBaseOpcode()
by addingENTER_EXECUTOR
handling. This will leave theoparg
incorrect. That's why that bullet in gh-107265 usesstrikethrough.