diff options
Diffstat (limited to 'Python/optimizer_analysis.c')
-rw-r--r-- | Python/optimizer_analysis.c | 87 |
1 files changed, 37 insertions, 50 deletions
diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 6c0aadb87e6..29a05088e62 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -93,26 +93,27 @@ type_watcher_callback(PyTypeObject* type) } static PyObject * -convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj) +convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj, bool pop) { - assert(inst->opcode == _LOAD_GLOBAL_MODULE || inst->opcode == _LOAD_GLOBAL_BUILTINS || inst->opcode == _LOAD_ATTR_MODULE_FROM_KEYS); + assert(inst->opcode == _LOAD_GLOBAL_MODULE || inst->opcode == _LOAD_GLOBAL_BUILTINS || inst->opcode == _LOAD_ATTR_MODULE); assert(PyDict_CheckExact(obj)); PyDictObject *dict = (PyDictObject *)obj; assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); - assert(inst->operand0 <= UINT16_MAX); - if ((int)inst->operand0 >= dict->ma_keys->dk_nentries) { + int64_t index = inst->operand1; + assert(index <= UINT16_MAX); + if ((int)index >= dict->ma_keys->dk_nentries) { return NULL; } - PyObject *res = entries[inst->operand0].me_value; + PyObject *res = entries[index].me_value; if (res == NULL) { return NULL; } if (_Py_IsImmortal(res)) { - inst->opcode = _LOAD_CONST_INLINE_BORROW; + inst->opcode = pop ? _POP_TOP_LOAD_CONST_INLINE_BORROW : _LOAD_CONST_INLINE_BORROW; } else { - inst->opcode = _LOAD_CONST_INLINE; + inst->opcode = pop ? _POP_TOP_LOAD_CONST_INLINE : _LOAD_CONST_INLINE; } if (inst->oparg & 1) { assert(inst[1].opcode == _PUSH_NULL_CONDITIONAL); @@ -198,21 +199,18 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, _PyUOpInstruction *inst = &buffer[pc]; int opcode = inst->opcode; switch(opcode) { - case _GUARD_BUILTINS_VERSION_PUSH_KEYS: - if (incorrect_keys(inst, builtins)) { + case _GUARD_GLOBALS_VERSION: + if (incorrect_keys(inst, globals)) { OPT_STAT_INC(remove_globals_incorrect_keys); return 0; } - if (interp->rare_events.builtin_dict >= _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) { - continue; - } - if (!check_next_uop(buffer, buffer_size, pc, - _LOAD_GLOBAL_BUILTINS_FROM_KEYS)) { + if (get_mutations(globals) >= _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) { continue; } - if ((builtins_watched & 1) == 0) { - PyDict_Watch(BUILTINS_WATCHER_ID, builtins); - builtins_watched |= 1; + if ((globals_watched & 1) == 0) { + PyDict_Watch(GLOBALS_WATCHER_ID, globals); + _Py_BloomFilter_Add(dependencies, globals); + globals_watched |= 1; } if (function_checked & 1) { buffer[pc].opcode = NOP; @@ -222,24 +220,29 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, buffer[pc].operand0 = function_version; function_checked |= 1; } - // We're no longer pushing the builtins keys; rewrite the - // instruction that consumed the keys to load them from the - // frame. - buffer[pc + 1].opcode = _LOAD_GLOBAL_BUILTINS; break; - case _GUARD_GLOBALS_VERSION: - case _GUARD_GLOBALS_VERSION_PUSH_KEYS: - if (incorrect_keys(inst, globals)) { + case _LOAD_GLOBAL_BUILTINS: + if (incorrect_keys(inst, builtins)) { OPT_STAT_INC(remove_globals_incorrect_keys); return 0; } - uint64_t watched_mutations = get_mutations(globals); - if (watched_mutations >= _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) { + if (interp->rare_events.builtin_dict >= _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) { continue; } - if (opcode == _GUARD_GLOBALS_VERSION_PUSH_KEYS && - !check_next_uop(buffer, buffer_size, pc, - _LOAD_GLOBAL_MODULE_FROM_KEYS)) { + if ((builtins_watched & 1) == 0) { + PyDict_Watch(BUILTINS_WATCHER_ID, builtins); + builtins_watched |= 1; + } + if (function_checked & globals_watched & 1) { + convert_global_to_const(inst, builtins, false); + } + break; + case _LOAD_GLOBAL_MODULE: + if (incorrect_keys(inst, globals)) { + OPT_STAT_INC(remove_globals_incorrect_keys); + return 0; + } + if (get_mutations(globals) >= _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) { continue; } if ((globals_watched & 1) == 0) { @@ -247,29 +250,13 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, _Py_BloomFilter_Add(dependencies, globals); globals_watched |= 1; } - if (function_checked & 1) { - buffer[pc].opcode = NOP; - } - else { - buffer[pc].opcode = _CHECK_FUNCTION; - buffer[pc].operand0 = function_version; + if ((function_checked & 1) == 0 && buffer[pc-1].opcode == _NOP) { + buffer[pc-1].opcode = _CHECK_FUNCTION; + buffer[pc-1].operand0 = function_version; function_checked |= 1; } - if (opcode == _GUARD_GLOBALS_VERSION_PUSH_KEYS) { - // We're no longer pushing the globals keys; rewrite the - // instruction that consumed the keys to load them from the - // frame. - buffer[pc + 1].opcode = _LOAD_GLOBAL_MODULE; - } - break; - case _LOAD_GLOBAL_BUILTINS: - if (function_checked & globals_watched & builtins_watched & 1) { - convert_global_to_const(inst, builtins); - } - break; - case _LOAD_GLOBAL_MODULE: - if (function_checked & globals_watched & 1) { - convert_global_to_const(inst, globals); + if (function_checked & 1) { + convert_global_to_const(inst, globals, false); } break; case _PUSH_FRAME: |