Skip to content

Commit 487861c

Browse files
authored
GH-104909: Split LOAD_ATTR_INSTANCE_VALUE into micro-ops (GH-106678)
1 parent 32718f9 commit 487861c

File tree

6 files changed

+87
-46
lines changed

6 files changed

+87
-46
lines changed

Include/internal/pycore_opcode_metadata.h

+13-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Split :opcode:`LOAD_ATTR_INSTANCE_VALUE` into micro-ops.

Python/bytecodes.c

+16-3
Original file line numberDiff line numberDiff line change
@@ -1816,14 +1816,21 @@ dummy_func(
18161816
LOAD_ATTR,
18171817
};
18181818

1819-
inst(LOAD_ATTR_INSTANCE_VALUE, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) {
1819+
op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) {
18201820
PyTypeObject *tp = Py_TYPE(owner);
18211821
assert(type_version != 0);
18221822
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
1823-
assert(tp->tp_dictoffset < 0);
1824-
assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT);
1823+
}
1824+
1825+
op(_CHECK_MANAGED_OBJECT_HAS_VALUES, (owner -- owner)) {
1826+
assert(Py_TYPE(owner)->tp_dictoffset < 0);
1827+
assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
18251828
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
18261829
DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR);
1830+
}
1831+
1832+
op(_LOAD_ATTR_INSTANCE_VALUE, (index/1, unused/5, owner -- res2 if (oparg & 1), res)) {
1833+
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
18271834
res = _PyDictOrValues_GetValues(dorv)->values[index];
18281835
DEOPT_IF(res == NULL, LOAD_ATTR);
18291836
STAT_INC(LOAD_ATTR, hit);
@@ -1832,6 +1839,12 @@ dummy_func(
18321839
DECREF_INPUTS();
18331840
}
18341841

1842+
macro(LOAD_ATTR_INSTANCE_VALUE) =
1843+
_SKIP_CACHE + // Skip over the counter
1844+
_GUARD_TYPE_VERSION +
1845+
_CHECK_MANAGED_OBJECT_HAS_VALUES +
1846+
_LOAD_ATTR_INSTANCE_VALUE;
1847+
18351848
inst(LOAD_ATTR_MODULE, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) {
18361849
DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR);
18371850
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;

Python/executor_cases.c.h

+18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

+38-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/generate_cases.py

+1-13
Original file line numberDiff line numberDiff line change
@@ -839,19 +839,7 @@ def map_families(self) -> None:
839839
)
840840
else:
841841
member_instr.family = family
842-
elif member_macro := self.macro_instrs.get(member):
843-
for part in member_macro.parts:
844-
if isinstance(part, Component):
845-
if part.instr.family not in (family, None):
846-
self.error(
847-
f"Component {part.instr.name} of macro {member} "
848-
f"is a member of multiple families "
849-
f"({part.instr.family.name}, {family.name}).",
850-
family,
851-
)
852-
else:
853-
part.instr.family = family
854-
else:
842+
elif not self.macro_instrs.get(member):
855843
self.error(
856844
f"Unknown instruction {member!r} referenced in family {family.name!r}",
857845
family,

0 commit comments

Comments
 (0)