diff options
| author | Saul Shanabrook <s.shanabrook@gmail.com> | 2024-06-08 09:41:45 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-08 09:41:45 (GMT) |
| commit | 55402d3232ca400ebafe4fe3bd70f252304ebe07 (patch) | |
| tree | ac32d1d0583c4a2e4f82a7352fdb836c49145d9a /Python/optimizer_cases.c.h | |
| parent | 2080425154d235b4b7dcc9a8a2f58e71769125ca (diff) | |
| download | cpython-55402d3232ca400ebafe4fe3bd70f252304ebe07.zip cpython-55402d3232ca400ebafe4fe3bd70f252304ebe07.tar.gz cpython-55402d3232ca400ebafe4fe3bd70f252304ebe07.tar.bz2 | |
gh-119258: Eliminate Type Guards in Tier 2 Optimizer with Watcher (GH-119365)
Co-authored-by: parmeggiani <parmeggiani@spaziodati.eu>
Co-authored-by: dpdani <git@danieleparmeggiani.me>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Brandt Bucher <brandtbucher@microsoft.com>
Co-authored-by: Ken Jin <kenjin@python.org>
Diffstat (limited to 'Python/optimizer_cases.c.h')
| -rw-r--r-- | Python/optimizer_cases.c.h | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index b378734..18f3ca4 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -930,6 +930,28 @@ } case _GUARD_TYPE_VERSION: { + _Py_UopsSymbol *owner; + owner = stack_pointer[-1]; + uint32_t type_version = (uint32_t)this_instr->operand; + assert(type_version); + if (sym_matches_type_version(owner, type_version)) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } else { + // add watcher so that whenever the type changes we invalidate this + PyTypeObject *type = _PyType_LookupByVersion(type_version); + // if the type is null, it was not found in the cache (there was a conflict) + // with the key, in which case we can't trust the version + if (type) { + // if the type version was set properly, then add a watcher + // if it wasn't this means that the type version was previously set to something else + // and we set the owner to bottom, so we don't need to add a watcher because we must have + // already added one earlier. + if (sym_set_type_version(owner, type_version)) { + PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type); + _Py_BloomFilter_Add(dependencies, type); + } + } + } break; } @@ -1583,16 +1605,11 @@ args--; argcount++; } - _Py_UopsSymbol **localsplus_start = ctx->n_consumed; - int n_locals_already_filled = 0; - // Can determine statically, so we interleave the new locals - // and make the current stack the new locals. - // This also sets up for true call inlining. if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { - localsplus_start = args; - n_locals_already_filled = argcount; + new_frame = frame_new(ctx, co, 0, args, argcount); + } else { + new_frame = frame_new(ctx, co, 0, NULL, 0); } - new_frame = frame_new(ctx, co, localsplus_start, n_locals_already_filled, 0); stack_pointer[-2 - oparg] = (_Py_UopsSymbol *)new_frame; stack_pointer += -1 - oparg; break; |
