mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-136125: Use _PyObject_GetMethodStackRef
for LOAD_ATTR
(GH-136127)
This commit is contained in:
parent
17cf0a343b
commit
e0d6500b2d
6 changed files with 29 additions and 32 deletions
|
@ -918,7 +918,7 @@ extern PyObject *_PyType_LookupRefAndVersion(PyTypeObject *, PyObject *,
|
||||||
extern unsigned int
|
extern unsigned int
|
||||||
_PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef *out);
|
_PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef *out);
|
||||||
|
|
||||||
extern int _PyObject_GetMethodStackRef(PyThreadState *ts, PyObject *obj,
|
PyAPI_FUNC(int) _PyObject_GetMethodStackRef(PyThreadState *ts, PyObject *obj,
|
||||||
PyObject *name, _PyStackRef *method);
|
PyObject *name, _PyStackRef *method);
|
||||||
|
|
||||||
// Cache the provided init method in the specialization cache of type if the
|
// Cache the provided init method in the specialization cache of type if the
|
||||||
|
|
|
@ -2327,19 +2327,18 @@ dummy_func(
|
||||||
#endif /* ENABLE_SPECIALIZATION_FT */
|
#endif /* ENABLE_SPECIALIZATION_FT */
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_LOAD_ATTR, (owner -- attr, self_or_null[oparg&1])) {
|
op(_LOAD_ATTR, (owner -- attr[1], self_or_null[oparg&1])) {
|
||||||
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
|
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
|
||||||
PyObject *attr_o;
|
|
||||||
if (oparg & 1) {
|
if (oparg & 1) {
|
||||||
/* Designed to work in tandem with CALL, pushes two values. */
|
/* Designed to work in tandem with CALL, pushes two values. */
|
||||||
attr_o = NULL;
|
*attr = PyStackRef_NULL;
|
||||||
int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
|
int is_meth = _PyObject_GetMethodStackRef(tstate, PyStackRef_AsPyObjectBorrow(owner), name, attr);
|
||||||
if (is_meth) {
|
if (is_meth) {
|
||||||
/* We can bypass temporary bound method object.
|
/* We can bypass temporary bound method object.
|
||||||
meth is unbound method and obj is self.
|
meth is unbound method and obj is self.
|
||||||
meth | self | arg1 | ... | argN
|
meth | self | arg1 | ... | argN
|
||||||
*/
|
*/
|
||||||
assert(attr_o != NULL); // No errors on this branch
|
assert(!PyStackRef_IsNull(*attr)); // No errors on this branch
|
||||||
self_or_null[0] = owner; // Transfer ownership
|
self_or_null[0] = owner; // Transfer ownership
|
||||||
DEAD(owner);
|
DEAD(owner);
|
||||||
}
|
}
|
||||||
|
@ -2351,17 +2350,17 @@ dummy_func(
|
||||||
meth | NULL | arg1 | ... | argN
|
meth | NULL | arg1 | ... | argN
|
||||||
*/
|
*/
|
||||||
PyStackRef_CLOSE(owner);
|
PyStackRef_CLOSE(owner);
|
||||||
ERROR_IF(attr_o == NULL);
|
ERROR_IF(PyStackRef_IsNull(*attr));
|
||||||
self_or_null[0] = PyStackRef_NULL;
|
self_or_null[0] = PyStackRef_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Classic, pushes one value. */
|
/* Classic, pushes one value. */
|
||||||
attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
|
PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
|
||||||
PyStackRef_CLOSE(owner);
|
PyStackRef_CLOSE(owner);
|
||||||
ERROR_IF(attr_o == NULL);
|
ERROR_IF(attr_o == NULL);
|
||||||
|
*attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||||
}
|
}
|
||||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro(LOAD_ATTR) =
|
macro(LOAD_ATTR) =
|
||||||
|
|
17
Python/executor_cases.c.h
generated
17
Python/executor_cases.c.h
generated
|
@ -3301,20 +3301,20 @@
|
||||||
|
|
||||||
case _LOAD_ATTR: {
|
case _LOAD_ATTR: {
|
||||||
_PyStackRef owner;
|
_PyStackRef owner;
|
||||||
_PyStackRef attr;
|
_PyStackRef *attr;
|
||||||
_PyStackRef *self_or_null;
|
_PyStackRef *self_or_null;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
owner = stack_pointer[-1];
|
owner = stack_pointer[-1];
|
||||||
|
attr = &stack_pointer[-1];
|
||||||
self_or_null = &stack_pointer[0];
|
self_or_null = &stack_pointer[0];
|
||||||
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
|
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
|
||||||
PyObject *attr_o;
|
|
||||||
if (oparg & 1) {
|
if (oparg & 1) {
|
||||||
attr_o = NULL;
|
*attr = PyStackRef_NULL;
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
|
int is_meth = _PyObject_GetMethodStackRef(tstate, PyStackRef_AsPyObjectBorrow(owner), name, attr);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
if (is_meth) {
|
if (is_meth) {
|
||||||
assert(attr_o != NULL);
|
assert(!PyStackRef_IsNull(*attr));
|
||||||
self_or_null[0] = owner;
|
self_or_null[0] = owner;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3323,7 +3323,7 @@
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
PyStackRef_CLOSE(owner);
|
PyStackRef_CLOSE(owner);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
if (attr_o == NULL) {
|
if (PyStackRef_IsNull(*attr)) {
|
||||||
JUMP_TO_ERROR();
|
JUMP_TO_ERROR();
|
||||||
}
|
}
|
||||||
self_or_null[0] = PyStackRef_NULL;
|
self_or_null[0] = PyStackRef_NULL;
|
||||||
|
@ -3332,7 +3332,7 @@
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
|
PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
stack_pointer += -1;
|
stack_pointer += -1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -3342,10 +3342,9 @@
|
||||||
if (attr_o == NULL) {
|
if (attr_o == NULL) {
|
||||||
JUMP_TO_ERROR();
|
JUMP_TO_ERROR();
|
||||||
}
|
}
|
||||||
|
*attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||||
stack_pointer += 1;
|
stack_pointer += 1;
|
||||||
}
|
}
|
||||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
|
||||||
stack_pointer[-1] = attr;
|
|
||||||
stack_pointer += (oparg&1);
|
stack_pointer += (oparg&1);
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
|
|
17
Python/generated_cases.c.h
generated
17
Python/generated_cases.c.h
generated
|
@ -7941,7 +7941,7 @@
|
||||||
_Py_CODEUNIT* const this_instr = next_instr - 10;
|
_Py_CODEUNIT* const this_instr = next_instr - 10;
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
_PyStackRef owner;
|
_PyStackRef owner;
|
||||||
_PyStackRef attr;
|
_PyStackRef *attr;
|
||||||
_PyStackRef *self_or_null;
|
_PyStackRef *self_or_null;
|
||||||
// _SPECIALIZE_LOAD_ATTR
|
// _SPECIALIZE_LOAD_ATTR
|
||||||
{
|
{
|
||||||
|
@ -7964,16 +7964,16 @@
|
||||||
/* Skip 8 cache entries */
|
/* Skip 8 cache entries */
|
||||||
// _LOAD_ATTR
|
// _LOAD_ATTR
|
||||||
{
|
{
|
||||||
|
attr = &stack_pointer[-1];
|
||||||
self_or_null = &stack_pointer[0];
|
self_or_null = &stack_pointer[0];
|
||||||
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
|
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
|
||||||
PyObject *attr_o;
|
|
||||||
if (oparg & 1) {
|
if (oparg & 1) {
|
||||||
attr_o = NULL;
|
*attr = PyStackRef_NULL;
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
|
int is_meth = _PyObject_GetMethodStackRef(tstate, PyStackRef_AsPyObjectBorrow(owner), name, attr);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
if (is_meth) {
|
if (is_meth) {
|
||||||
assert(attr_o != NULL);
|
assert(!PyStackRef_IsNull(*attr));
|
||||||
self_or_null[0] = owner;
|
self_or_null[0] = owner;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -7982,7 +7982,7 @@
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
PyStackRef_CLOSE(owner);
|
PyStackRef_CLOSE(owner);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
if (attr_o == NULL) {
|
if (PyStackRef_IsNull(*attr)) {
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
self_or_null[0] = PyStackRef_NULL;
|
self_or_null[0] = PyStackRef_NULL;
|
||||||
|
@ -7991,7 +7991,7 @@
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
|
PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
stack_pointer += -1;
|
stack_pointer += -1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -8001,11 +8001,10 @@
|
||||||
if (attr_o == NULL) {
|
if (attr_o == NULL) {
|
||||||
JUMP_TO_LABEL(error);
|
JUMP_TO_LABEL(error);
|
||||||
}
|
}
|
||||||
|
*attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||||
stack_pointer += 1;
|
stack_pointer += 1;
|
||||||
}
|
}
|
||||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
|
||||||
}
|
}
|
||||||
stack_pointer[-1] = attr;
|
|
||||||
stack_pointer += (oparg&1);
|
stack_pointer += (oparg&1);
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
|
|
|
@ -590,9 +590,9 @@ dummy_func(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_LOAD_ATTR, (owner -- attr, self_or_null[oparg&1])) {
|
op(_LOAD_ATTR, (owner -- attr[1], self_or_null[oparg&1])) {
|
||||||
(void)owner;
|
(void)owner;
|
||||||
attr = sym_new_not_null(ctx);
|
*attr = sym_new_not_null(ctx);
|
||||||
if (oparg & 1) {
|
if (oparg & 1) {
|
||||||
self_or_null[0] = sym_new_unknown(ctx);
|
self_or_null[0] = sym_new_unknown(ctx);
|
||||||
}
|
}
|
||||||
|
|
6
Python/optimizer_cases.c.h
generated
6
Python/optimizer_cases.c.h
generated
|
@ -1414,16 +1414,16 @@
|
||||||
|
|
||||||
case _LOAD_ATTR: {
|
case _LOAD_ATTR: {
|
||||||
JitOptRef owner;
|
JitOptRef owner;
|
||||||
JitOptRef attr;
|
JitOptRef *attr;
|
||||||
JitOptRef *self_or_null;
|
JitOptRef *self_or_null;
|
||||||
owner = stack_pointer[-1];
|
owner = stack_pointer[-1];
|
||||||
|
attr = &stack_pointer[-1];
|
||||||
self_or_null = &stack_pointer[0];
|
self_or_null = &stack_pointer[0];
|
||||||
(void)owner;
|
(void)owner;
|
||||||
attr = sym_new_not_null(ctx);
|
*attr = sym_new_not_null(ctx);
|
||||||
if (oparg & 1) {
|
if (oparg & 1) {
|
||||||
self_or_null[0] = sym_new_unknown(ctx);
|
self_or_null[0] = sym_new_unknown(ctx);
|
||||||
}
|
}
|
||||||
stack_pointer[-1] = attr;
|
|
||||||
stack_pointer += (oparg&1);
|
stack_pointer += (oparg&1);
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue