Skip to content

Store both function and code object in the function version cache #117045

Closed
@gvanrossum

Description

@gvanrossum

(Copied from faster-cpython/ideas#665.)

The idea here is to avoid function version cache misses for generator expressions. (See faster-cpython/ideas#664 (comment).)

We have a complicated mechanism to reset the function version whenever __code__, __defaults__ and a few other critical attributes are mutated. (BTW: nothing is affected by changes to __annotations__, and yet that is also considered critical; I will fix this.)

Why not instead just reset the function version to zero and stick to that? We then guarantee that the function version is either zero or matches the code object version.

Nothing changes for specialization except that _PyFunction_GetVersionForCurrentState() returns 0 for mutated functions. This is unlikely to affect any benchmark or other perf-critical real-world code.

The function version cache will double in size, and store both the function and the code object. When a function is deallocated or its version is reset to zero, it evicts itself from the cache, but keeps the code object. Code objects remove themselves from the cache when deallocated (and probably also evict the function object).

For Tier 2, when generating _PUSH_FRAME or _POP_FRAME, we can handle the case where the function version maps to a pair (NULL, some_code_object) -- we store NULL in the operand, but we use some_code_object to trace through. Globals removal will no longer work (boo hoo), but at least we still have a trace. Presumably at least some generator expressions don't use globals (they can still use builtins, which can be reached without the function object).

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions