Skip to content

Commit 3aa12d8

Browse files
committed
Remove conditional stack effects from LOAD_ATTR
1 parent bfa374e commit 3aa12d8

File tree

7 files changed

+33
-134
lines changed

7 files changed

+33
-134
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_monitoring.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,8 +1138,8 @@ def func2():
11381138
('call', 'func2', sys.monitoring.MISSING),
11391139
('line', 'func2', 1),
11401140
('line', 'func2', 2),
1141-
('call', 'append', [2]),
1142-
('C return', 'append', [2]),
1141+
('call', 'append', 2),
1142+
('C return', 'append', 2),
11431143
('line', 'func2', 3),
11441144
('line', 'get_events', 11),
11451145
('call', 'set_events', 2)])
@@ -1434,8 +1434,8 @@ def func2():
14341434
self.check_events(func2, recorders = LOCAL_RECORDERS, expected = [
14351435
('line', 'func2', 1),
14361436
('line', 'func2', 2),
1437-
('call', 'append', [2]),
1438-
('C return', 'append', [2]),
1437+
('call', 'append', 2),
1438+
('C return', 'append', 2),
14391439
('line', 'func2', 3)])
14401440

14411441
def test_try_except(self):
@@ -1913,7 +1913,6 @@ def f():
19131913
""")
19141914

19151915
def get_expected(name, call_method, ns):
1916-
repr_arg = 0 if name == "int" else sys.monitoring.MISSING
19171916
return [
19181917
('line', 'get_events', 10),
19191918
('call', 'f', sys.monitoring.MISSING),
@@ -1924,8 +1923,8 @@ def get_expected(name, call_method, ns):
19241923
('C return', name, sys.monitoring.MISSING),
19251924
*(
19261925
[
1927-
('call', '__repr__', repr_arg),
1928-
('C return', '__repr__', repr_arg),
1926+
('call', '__repr__', sys.monitoring.MISSING),
1927+
('C return', '__repr__', sys.monitoring.MISSING),
19291928
] if call_method else []
19301929
),
19311930
('line', 'get_events', 11),

Python/bytecodes.c

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,49 +2155,19 @@ dummy_func(
21552155
#endif /* ENABLE_SPECIALIZATION_FT */
21562156
}
21572157

2158-
op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
2158+
op(_LOAD_ATTR, (owner -- attr)) {
21592159
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
2160-
PyObject *attr_o;
2161-
if (oparg & 1) {
2162-
/* Designed to work in tandem with CALL, pushes two values. */
2163-
attr_o = NULL;
2164-
int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o);
2165-
if (is_meth) {
2166-
/* We can bypass temporary bound method object.
2167-
meth is unbound method and obj is self.
2168-
meth | self | arg1 | ... | argN
2169-
*/
2170-
assert(attr_o != NULL); // No errors on this branch
2171-
self_or_null = owner; // Transfer ownership
2172-
DEAD(owner);
2173-
}
2174-
else {
2175-
/* meth is not an unbound method (but a regular attr, or
2176-
something was returned by a descriptor protocol). Set
2177-
the second element of the stack to NULL, to signal
2178-
CALL that it's not a method call.
2179-
meth | NULL | arg1 | ... | argN
2180-
*/
2181-
DECREF_INPUTS();
2182-
ERROR_IF(attr_o == NULL, error);
2183-
self_or_null = PyStackRef_NULL;
2184-
}
2185-
}
2186-
else {
2187-
/* Classic, pushes one value. */
2188-
attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
2189-
DECREF_INPUTS();
2190-
ERROR_IF(attr_o == NULL, error);
2191-
/* We need to define self_or_null on all paths */
2192-
self_or_null = PyStackRef_NULL;
2193-
}
2160+
PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
2161+
DECREF_INPUTS();
2162+
ERROR_IF(attr_o == NULL, error);
21942163
attr = PyStackRef_FromPyObjectSteal(attr_o);
21952164
}
21962165

21972166
macro(LOAD_ATTR) =
21982167
_SPECIALIZE_LOAD_ATTR +
21992168
unused/8 +
2200-
_LOAD_ATTR;
2169+
_LOAD_ATTR +
2170+
_PUSH_NULL_CONDITIONAL;
22012171

22022172
op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) {
22032173
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
@@ -2223,7 +2193,7 @@ dummy_func(
22232193
DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid));
22242194
}
22252195

2226-
split op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr)) {
2196+
op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr)) {
22272197
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
22282198
PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset);
22292199
PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr);
@@ -2340,7 +2310,7 @@ dummy_func(
23402310
unused/5 +
23412311
_PUSH_NULL_CONDITIONAL;
23422312

2343-
split op(_LOAD_ATTR_SLOT, (index/1, owner -- attr)) {
2313+
op(_LOAD_ATTR_SLOT, (index/1, owner -- attr)) {
23442314
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
23452315

23462316
PyObject **addr = (PyObject **)((char *)owner_o + index);
@@ -2371,7 +2341,7 @@ dummy_func(
23712341
EXIT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(((PyTypeObject *)owner_o)->tp_version_tag) != type_version);
23722342
}
23732343

2374-
split op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr)) {
2344+
op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr)) {
23752345
STAT_INC(LOAD_ATTR, hit);
23762346
assert(descr != NULL);
23772347
attr = PyStackRef_FromPyObjectNew(descr);

Python/executor_cases.c.h

Lines changed: 5 additions & 41 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 11 additions & 39 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer_bytecodes.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,9 @@ dummy_func(void) {
548548
null = sym_new_null(ctx);
549549
}
550550

551-
op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
551+
op(_LOAD_ATTR, (owner -- attr)) {
552552
(void)owner;
553553
attr = sym_new_not_null(ctx);
554-
self_or_null = sym_new_unknown(ctx);
555554
}
556555

557556
op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys -- attr)) {

Python/optimizer_cases.c.h

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)