Skip to content

Bad specialization of STORE_ATTR_INSTANCE_VALUE with obj.__dict__ #125610

Description

@colesbury

Consider:

class MyObject: pass

def func():
    o = MyObject()
    o.__dict__
    for _ in range(100):
        o.foo = "bar"
        o.baz = "qux"

for _ in range(100):
    func()
    opcode[STORE_ATTR_INSTANCE_VALUE].specialization.miss : 20382
    opcode[STORE_ATTR_INSTANCE_VALUE].execution_count : 21167

The STORE_ATTR_INSTANCE_VALUE has a guard _GUARD_DORV_NO_DICT that ensures that the object does not have a managed dictionary:

EXIT_IF(_PyObject_GetManagedDict(owner_o));

However, the specializer for STORE_ATTR_INSTANCE_VALUE does not take that into account. It only checks that the inline values are valid:

cpython/Python/specialize.c

Lines 867 to 886 in 760872e

if (type->tp_flags & Py_TPFLAGS_INLINE_VALUES && _PyObject_InlineValues(owner)->valid) {
PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys;
assert(PyUnicode_CheckExact(name));
Py_ssize_t index = _PyDictKeys_StringLookup(keys, name);
assert (index != DKIX_ERROR);
if (index == DKIX_EMPTY) {
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NOT_IN_KEYS);
return 0;
}
assert(index >= 0);
char *value_addr = (char *)&_PyObject_InlineValues(owner)->values[index];
Py_ssize_t offset = value_addr - (char *)owner;
if (offset != (uint16_t)offset) {
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE);
return 0;
}
write_u32(cache->version, type->tp_version_tag);
cache->index = (uint16_t)offset;
instr->op.code = values_op;
}

I'm not sure if we should change the guard or change specialize.c

Linked PRs

Activity

  1. added
    performancePerformance or resource usage
    3.13only security fixes
    3.14bugs and security fixes
    on Oct 16, 2024
  2. added a commit that references this issue on Oct 16, 2024
  3. added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    type-bugAn unexpected behavior, bug, or error
    on Oct 21, 2024
  4. added 2 commits that reference this issue on Dec 4, 2024
  5. added a commit that references this issue on Dec 6, 2024
  6. added a commit that references this issue on Dec 6, 2024
  7. added a commit that references this issue on Jan 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13only security fixes3.14bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagetype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions