Skip to content

Stop using OnceCell for PackedInstruction.py_op field #13219

@mtreinish

Description

@mtreinish

What should we add?

When the cache_pygates feature is enabled, the py_op field in the PackedInstruction struct stores a OnceCell<PyObject> right now. See:

#[cfg(feature = "cache_pygates")]
/// This is hidden in a `OnceCell` because it's just an on-demand cache; we don't create this
/// unless asked for it. A `OnceCell` of a non-null pointer type (like `Py<T>`) is the same
/// size as a pointer and there are no runtime checks on access beyond the initialisation check,
/// which is a simple null-pointer check.
///
/// WARNING: remember that `OnceCell`'s `get_or_init` method is no-reentrant, so the initialiser
/// must not yield the GIL to Python space. We avoid using `GILOnceCell` here because it
/// requires the GIL to even `get` (of course!), which makes implementing `Clone` hard for us.
/// We can revisit once we're on PyO3 0.22+ and have been able to disable its `py-clone`
/// feature.
pub py_op: OnceCell<Py<PyAny>>,
this is used a cached python object for the underlying instruction so we don't repeatedly rebuild the objects when returning to python. However the use of a OnceCell in this field is preventing us from enabling the pygate cache and writing multithreaded transpiler passes as it is not thread-safe. The logical alternative is GilOnceCell which uses the GIL as a lock for a threadsafe version, but it isn't cloneable (which is commented on in the code). The other alternative is OnceLock but that likely will add some overhead to the pygate cache as we're adding an additional locking mechanism.

Metadata

Metadata

Assignees

No one assigned

    Labels

    RustThis PR or issue is related to Rust code in the repository

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions