Skip to content

Commit 5693f45

Browse files
authored
Assorted minor fixes for specialization stats. (GH-100219)
1 parent 3192c00 commit 5693f45

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

Python/specialize.c

+34-17
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ _PyCode_Quicken(PyCodeObject *code)
307307
#define SPEC_FAIL_NOT_PY_FUNCTION 7
308308

309309

310+
#define SPEC_FAIL_LOAD_GLOBAL_NON_DICT 17
310311
#define SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT 18
311312

312313
/* Attributes */
@@ -332,6 +333,8 @@ _PyCode_Quicken(PyCodeObject *code)
332333
#define SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE 26
333334
#define SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE 27
334335
#define SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION 28
336+
#define SPEC_FAIL_ATTR_NOT_IN_KEYS 29
337+
#define SPEC_FAIL_ATTR_NOT_IN_DICT 30
335338

336339
/* Binary subscr and store subscr */
337340

@@ -448,41 +451,44 @@ static bool function_check_args(PyObject *o, int expected_argcount, int opcode);
448451
static uint32_t function_get_version(PyObject *o, int opcode);
449452

450453
static int
451-
specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
452-
PyObject *name, int opcode, int opcode_module)
453-
{
454+
specialize_module_load_attr(
455+
PyObject *owner, _Py_CODEUNIT *instr, PyObject *name
456+
) {
454457
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
455458
PyModuleObject *m = (PyModuleObject *)owner;
456459
assert((owner->ob_type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0);
457460
PyDictObject *dict = (PyDictObject *)m->md_dict;
458461
if (dict == NULL) {
459-
SPECIALIZATION_FAIL(opcode, SPEC_FAIL_NO_DICT);
462+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_NO_DICT);
460463
return -1;
461464
}
462465
if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
463-
SPECIALIZATION_FAIL(opcode, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT);
466+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT);
464467
return -1;
465468
}
466469
Py_ssize_t index = _PyDict_LookupIndex(dict, &_Py_ID(__getattr__));
467470
assert(index != DKIX_ERROR);
468471
if (index != DKIX_EMPTY) {
469-
SPECIALIZATION_FAIL(opcode, SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND);
472+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND);
470473
return -1;
471474
}
472475
index = _PyDict_LookupIndex(dict, name);
473476
assert (index != DKIX_ERROR);
474477
if (index != (uint16_t)index) {
475-
SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_RANGE);
478+
SPECIALIZATION_FAIL(LOAD_ATTR,
479+
index == DKIX_EMPTY ?
480+
SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND :
481+
SPEC_FAIL_OUT_OF_RANGE);
476482
return -1;
477483
}
478484
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(dict->ma_keys);
479485
if (keys_version == 0) {
480-
SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS);
486+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
481487
return -1;
482488
}
483489
write_u32(cache->version, keys_version);
484490
cache->index = (uint16_t)index;
485-
_py_set_opocde(instr, opcode_module);
491+
_py_set_opocde(instr, LOAD_ATTR_MODULE);
486492
return 0;
487493
}
488494

@@ -629,7 +635,10 @@ specialize_dict_access(
629635
Py_ssize_t index = _PyDictKeys_StringLookup(keys, name);
630636
assert (index != DKIX_ERROR);
631637
if (index != (uint16_t)index) {
632-
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE);
638+
SPECIALIZATION_FAIL(base_op,
639+
index == DKIX_EMPTY ?
640+
SPEC_FAIL_ATTR_NOT_IN_KEYS :
641+
SPEC_FAIL_OUT_OF_RANGE);
633642
return 0;
634643
}
635644
write_u32(cache->version, type->tp_version_tag);
@@ -646,7 +655,10 @@ specialize_dict_access(
646655
Py_ssize_t index =
647656
_PyDict_LookupIndex(dict, name);
648657
if (index != (uint16_t)index) {
649-
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE);
658+
SPECIALIZATION_FAIL(base_op,
659+
index == DKIX_EMPTY ?
660+
SPEC_FAIL_ATTR_NOT_IN_DICT :
661+
SPEC_FAIL_OUT_OF_RANGE);
650662
return 0;
651663
}
652664
cache->index = (uint16_t)index;
@@ -674,8 +686,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
674686
goto fail;
675687
}
676688
if (PyModule_CheckExact(owner)) {
677-
if (specialize_module_load_attr(owner, instr, name, LOAD_ATTR,
678-
LOAD_ATTR_MODULE))
689+
if (specialize_module_load_attr(owner, instr, name))
679690
{
680691
goto fail;
681692
}
@@ -702,7 +713,9 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
702713
goto success;
703714
}
704715
}
705-
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
716+
else {
717+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD);
718+
}
706719
goto fail;
707720
}
708721
case PROPERTY:
@@ -1076,7 +1089,6 @@ PyObject *descr, DescriptorClassification kind)
10761089
*/
10771090
write_u32(cache->type_version, owner_cls->tp_version_tag);
10781091
write_obj(cache->descr, descr);
1079-
// Fall through.
10801092
return 1;
10811093
fail:
10821094
return 0;
@@ -1092,6 +1104,7 @@ _Py_Specialize_LoadGlobal(
10921104
_PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr + 1);
10931105
assert(PyUnicode_CheckExact(name));
10941106
if (!PyDict_CheckExact(globals)) {
1107+
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_DICT);
10951108
goto fail;
10961109
}
10971110
PyDictKeysObject * globals_keys = ((PyDictObject *)globals)->ma_keys;
@@ -1101,15 +1114,17 @@ _Py_Specialize_LoadGlobal(
11011114
}
11021115
Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name);
11031116
if (index == DKIX_ERROR) {
1104-
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT);
1117+
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR);
11051118
goto fail;
11061119
}
11071120
if (index != DKIX_EMPTY) {
11081121
if (index != (uint16_t)index) {
1122+
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
11091123
goto fail;
11101124
}
11111125
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(globals_keys);
11121126
if (keys_version == 0) {
1127+
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
11131128
goto fail;
11141129
}
11151130
cache->index = (uint16_t)index;
@@ -1118,6 +1133,7 @@ _Py_Specialize_LoadGlobal(
11181133
goto success;
11191134
}
11201135
if (!PyDict_CheckExact(builtins)) {
1136+
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_DICT);
11211137
goto fail;
11221138
}
11231139
PyDictKeysObject * builtin_keys = ((PyDictObject *)builtins)->ma_keys;
@@ -1127,10 +1143,11 @@ _Py_Specialize_LoadGlobal(
11271143
}
11281144
index = _PyDictKeys_StringLookup(builtin_keys, name);
11291145
if (index == DKIX_ERROR) {
1130-
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT);
1146+
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR);
11311147
goto fail;
11321148
}
11331149
if (index != (uint16_t)index) {
1150+
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
11341151
goto fail;
11351152
}
11361153
uint32_t globals_version = _PyDictKeys_GetVersionForCurrentState(globals_keys);

Tools/scripts/summarize_stats.py

+5-10
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
opmap = {name: i for i, name in enumerate(opname)}
3333
opmap = dict(sorted(opmap.items()))
3434

35-
TOTAL = "specialization.deferred", "specialization.hit", "specialization.miss", "execution_count"
35+
TOTAL = "specialization.hit", "specialization.miss", "execution_count"
3636

3737
def format_ratio(num, den):
3838
"""
@@ -90,7 +90,7 @@ def calculate_specialization_stats(family_stats, total):
9090
if key in ("specialization.hit", "specialization.miss"):
9191
label = key[len("specialization."):]
9292
elif key == "execution_count":
93-
label = "unquickened"
93+
continue
9494
elif key in ("specialization.success", "specialization.failure", "specializable"):
9595
continue
9696
elif key.startswith("pair"):
@@ -115,7 +115,7 @@ def calculate_specialization_success_failure(family_stats):
115115

116116
def calculate_specialization_failure_kinds(name, family_stats, defines):
117117
total_failures = family_stats.get("specialization.failure", 0)
118-
failure_kinds = [ 0 ] * 30
118+
failure_kinds = [ 0 ] * 40
119119
for key in family_stats:
120120
if not key.startswith("specialization.failure_kind"):
121121
continue
@@ -224,7 +224,7 @@ def pretty(defname):
224224
return defname.replace("_", " ").lower()
225225

226226
def kind_to_text(kind, defines, opname):
227-
if kind < 7:
227+
if kind <= 7:
228228
return pretty(defines[kind][0])
229229
if opname.endswith("ATTR"):
230230
opname = "ATTR"
@@ -241,19 +241,14 @@ def categorized_counts(opcode_stats):
241241
not_specialized = 0
242242
specialized_instructions = {
243243
op for op in opcode._specialized_instructions
244-
if "__" not in op and "ADAPTIVE" not in op}
245-
adaptive_instructions = {
246-
op for op in opcode._specialized_instructions
247-
if "ADAPTIVE" in op}
244+
if "__" not in op}
248245
for i, opcode_stat in enumerate(opcode_stats):
249246
if "execution_count" not in opcode_stat:
250247
continue
251248
count = opcode_stat['execution_count']
252249
name = opname[i]
253250
if "specializable" in opcode_stat:
254251
not_specialized += count
255-
elif name in adaptive_instructions:
256-
not_specialized += count
257252
elif name in specialized_instructions:
258253
miss = opcode_stat.get("specialization.miss", 0)
259254
not_specialized += miss

0 commit comments

Comments
 (0)