Generate a definition of a single-object per-class free "list". This speeds up object allocation and freeing when there are many short-lived objects. TODO: Generalize to support a free list with up to N objects.
(
cl: ClassIR, c_emitter: Emitter, external_emitter: Emitter, emitter: Emitter
)
| 215 | |
| 216 | |
| 217 | def generate_class_reuse( |
| 218 | cl: ClassIR, c_emitter: Emitter, external_emitter: Emitter, emitter: Emitter |
| 219 | ) -> None: |
| 220 | """Generate a definition of a single-object per-class free "list". |
| 221 | |
| 222 | This speeds up object allocation and freeing when there are many short-lived |
| 223 | objects. |
| 224 | |
| 225 | TODO: Generalize to support a free list with up to N objects. |
| 226 | """ |
| 227 | assert cl.reuse_freed_instance |
| 228 | context = c_emitter.context |
| 229 | name = cl.name_prefix(c_emitter.names) + "_free_instance" |
| 230 | struct_name = cl.struct_name(c_emitter.names) |
| 231 | # Not exported: the free-instance slot is only read/written by the class's |
| 232 | # own setup/dealloc code, which lives in the defining group. Exporting it |
| 233 | # also trips a C diagnostic under `Py_GIL_DISABLED`, where `CPyThreadLocal` |
| 234 | # expands to `__thread` and can't legally appear inside the exports struct. |
| 235 | context.declarations[name] = HeaderDeclaration(f"CPyThreadLocal {struct_name} *{name};") |
| 236 | |
| 237 | |
| 238 | def generate_class(cl: ClassIR, module: str, emitter: Emitter) -> None: |
no test coverage detected
searching dependent graphs…