summaryrefslogtreecommitdiffstats
path: root/Python/optimizer_bytecodes.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/optimizer_bytecodes.c')
-rw-r--r--Python/optimizer_bytecodes.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index a2cb4c0..e6fb85a 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -21,11 +21,13 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
#define sym_new_const _Py_uop_sym_new_const
#define sym_new_null _Py_uop_sym_new_null
#define sym_matches_type _Py_uop_sym_matches_type
+#define sym_matches_type_version _Py_uop_sym_matches_type_version
#define sym_get_type _Py_uop_sym_get_type
#define sym_has_type _Py_uop_sym_has_type
#define sym_set_null(SYM) _Py_uop_sym_set_null(ctx, SYM)
#define sym_set_non_null(SYM) _Py_uop_sym_set_non_null(ctx, SYM)
#define sym_set_type(SYM, TYPE) _Py_uop_sym_set_type(ctx, SYM, TYPE)
+#define sym_set_type_version(SYM, VERSION) _Py_uop_sym_set_type_version(ctx, SYM, VERSION)
#define sym_set_const(SYM, CNST) _Py_uop_sym_set_const(ctx, SYM, CNST)
#define sym_is_bottom _Py_uop_sym_is_bottom
#define frame_new _Py_uop_frame_new
@@ -113,6 +115,29 @@ dummy_func(void) {
sym_set_type(right, &PyLong_Type);
}
+ op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) {
+ 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);
+ }
+ }
+
+ }
+ }
+
op(_GUARD_BOTH_FLOAT, (left, right -- left, right)) {
if (sym_matches_type(left, &PyFloat_Type)) {
if (sym_matches_type(right, &PyFloat_Type)) {
@@ -563,16 +588,12 @@ dummy_func(void) {
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);
}
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _Py_UOpsAbstractFrame *)) {