Skip to content

Commit cc16f6f

Browse files
committed
gh-148510: restore func_version check in _LOAD_ATTR_PROPERTY_FRAME
1 parent 4bc0a97 commit cc16f6f

File tree

4 files changed

+47
-12
lines changed

4 files changed

+47
-12
lines changed

Include/internal/pycore_optimizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ extern JitOptRef _Py_uop_sym_new_null(JitOptContext *ctx);
400400
extern bool _Py_uop_sym_has_type(JitOptRef sym);
401401
extern bool _Py_uop_sym_matches_type(JitOptRef sym, PyTypeObject *typ);
402402
extern bool _Py_uop_sym_matches_type_version(JitOptRef sym, unsigned int version);
403+
extern unsigned int _Py_uop_sym_get_type_version(JitOptRef sym);
403404
extern void _Py_uop_sym_set_null(JitOptContext *ctx, JitOptRef sym);
404405
extern void _Py_uop_sym_set_non_null(JitOptContext *ctx, JitOptRef sym);
405406
extern void _Py_uop_sym_set_type(JitOptContext *ctx, JitOptRef sym, PyTypeObject *typ);

Python/optimizer_analysis.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ add_op(JitOptContext *ctx, _PyUOpInstruction *this_instr,
257257
#define sym_get_probable_type _Py_uop_sym_get_probable_type
258258
#define sym_matches_type _Py_uop_sym_matches_type
259259
#define sym_matches_type_version _Py_uop_sym_matches_type_version
260+
#define sym_get_type_version _Py_uop_sym_get_type_version
260261
#define sym_set_null(SYM) _Py_uop_sym_set_null(ctx, SYM)
261262
#define sym_set_non_null(SYM) _Py_uop_sym_set_non_null(ctx, SYM)
262263
#define sym_set_type(SYM, TYPE) _Py_uop_sym_set_type(ctx, SYM, TYPE)

Python/optimizer_bytecodes.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
2020
#define sym_new_null _Py_uop_sym_new_null
2121
#define sym_matches_type _Py_uop_sym_matches_type
2222
#define sym_matches_type_version _Py_uop_sym_matches_type_version
23+
#define sym_get_type_version _Py_uop_sym_get_type_version
2324
#define sym_get_type _Py_uop_sym_get_type
2425
#define sym_has_type _Py_uop_sym_has_type
2526
#define sym_set_null(SYM) _Py_uop_sym_set_null(ctx, SYM)
@@ -138,15 +139,24 @@ dummy_func(void) {
138139
assert(type_version);
139140
if (sym_matches_type_version(owner, type_version)) {
140141
ADD_OP(_NOP, 0, 0);
141-
} else {
142+
}
143+
else {
142144
PyTypeObject *probable_type = sym_get_probable_type(owner);
143-
if (probable_type->tp_version_tag == type_version && sym_set_type_version(owner, type_version)) {
145+
if (probable_type != NULL &&
146+
probable_type->tp_version_tag == type_version) {
144147
// Promote the probable type version to a known one.
148+
sym_set_type(owner, probable_type);
149+
sym_set_type_version(owner, type_version);
145150
if ((probable_type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
146151
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type);
147152
_Py_BloomFilter_Add(dependencies, probable_type);
148153
}
149154
}
155+
else {
156+
ctx->contradiction = true;
157+
ctx->done = true;
158+
break;
159+
}
150160
}
151161
}
152162

@@ -239,14 +249,17 @@ dummy_func(void) {
239249
assert(this_instr[-1].opcode == _RECORD_TOS_TYPE);
240250
if (sym_matches_type_version(owner, type_version)) {
241251
ADD_OP(_NOP, 0, 0);
242-
} else {
252+
}
253+
else {
243254
PyTypeObject *probable_type = sym_get_probable_type(owner);
244255
if (probable_type != NULL &&
245-
probable_type->tp_version_tag == type_version &&
246-
sym_set_type_version(owner, type_version)) {
256+
probable_type->tp_version_tag == type_version) {
257+
sym_set_type(owner, probable_type);
258+
sym_set_type_version(owner, type_version);
247259
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type);
248260
_Py_BloomFilter_Add(dependencies, probable_type);
249-
} else {
261+
}
262+
else {
250263
ctx->contradiction = true;
251264
ctx->done = true;
252265
break;
@@ -981,6 +994,10 @@ dummy_func(void) {
981994
}
982995

983996
op(_LOAD_ATTR_PROPERTY_FRAME, (func_version/2, fget/4, owner -- new_frame)) {
997+
if (sym_get_type_version(owner) == 0) {
998+
ctx->done = true;
999+
break;
1000+
}
9841001
PyFunctionObject *func = (PyFunctionObject *)fget;
9851002
if (func->func_version != func_version) {
9861003
ctx->contradiction = true;

Python/optimizer_cases.c.h

Lines changed: 22 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)