Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f012df7

Browse filesBrowse files
authored
Shrink the LOAD_METHOD cache by one codeunit. (#93537)
1 parent 75ceae0 commit f012df7
Copy full SHA for f012df7

File tree

Expand file treeCollapse file tree

8 files changed

+12
-18
lines changed
Filter options
Expand file treeCollapse file tree

8 files changed

+12
-18
lines changed

‎Include/internal/pycore_code.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_code.h
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ typedef struct {
6565
typedef struct {
6666
_Py_CODEUNIT counter;
6767
_Py_CODEUNIT type_version[2];
68-
_Py_CODEUNIT dict_offset;
6968
_Py_CODEUNIT keys_version[2];
7069
_Py_CODEUNIT descr[4];
7170
} _PyLoadMethodCache;

‎Include/internal/pycore_opcode.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_opcode.h
+1-1Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Lib/importlib/_bootstrap_external.py

Copy file name to clipboardExpand all lines: Lib/importlib/_bootstrap_external.py
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ def _write_atomic(path, data, mode=0o666):
407407
# Python 3.12a1 3500 (Remove PRECALL opcode)
408408
# Python 3.12a1 3501 (YIELD_VALUE oparg == stack_depth)
409409
# Python 3.12a1 3502 (LOAD_FAST_CHECK, no NULL-check in LOAD_FAST)
410+
# Python 3.12a1 3503 (Shrink LOAD_METHOD cache)
410411

411412
# Python 3.13 will start with 3550
412413

@@ -420,7 +421,7 @@ def _write_atomic(path, data, mode=0o666):
420421
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
421422
# in PC/launcher.c must also be updated.
422423

423-
MAGIC_NUMBER = (3502).to_bytes(2, 'little') + b'\r\n'
424+
MAGIC_NUMBER = (3503).to_bytes(2, 'little') + b'\r\n'
424425

425426
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
426427

‎Lib/opcode.py

Copy file name to clipboardExpand all lines: Lib/opcode.py
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,6 @@ def jabs_op(name, op):
383383
"LOAD_METHOD": {
384384
"counter": 1,
385385
"type_version": 2,
386-
"dict_offset": 1,
387386
"keys_version": 2,
388387
"descr": 4,
389388
},

‎Lib/test/test_dis.py

Copy file name to clipboardExpand all lines: Lib/test/test_dis.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@ def test_show_caches(self):
10471047
for cache in caches:
10481048
self.assertRegex(cache, pattern)
10491049
self.assertEqual(caches.count(""), 8)
1050-
self.assertEqual(len(caches), 23)
1050+
self.assertEqual(len(caches), 22)
10511051

10521052

10531053
class DisWithFileTests(DisTests):
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reduce the size of the inline cache for ``LOAD_METHOD`` by 2 bytes.

‎Python/ceval.c

Copy file name to clipboardExpand all lines: Python/ceval.c
+4-7Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4581,12 +4581,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
45814581
DEOPT_IF(self_cls->tp_version_tag != read_u32(cache->type_version),
45824582
LOAD_METHOD);
45834583
/* Treat index as a signed 16 bit value */
4584-
int dictoffset = *(int16_t *)&cache->dict_offset;
4584+
int dictoffset = self_cls->tp_dictoffset;
4585+
assert(dictoffset > 0);
45854586
PyDictObject **dictptr = (PyDictObject**)(((char *)self)+dictoffset);
4586-
assert(
4587-
dictoffset == MANAGED_DICT_OFFSET ||
4588-
(dictoffset == self_cls->tp_dictoffset && dictoffset > 0)
4589-
);
45904587
PyDictObject *dict = *dictptr;
45914588
DEOPT_IF(dict == NULL, LOAD_METHOD);
45924589
DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->keys_version),
@@ -4628,9 +4625,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
46284625
_PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr;
46294626
uint32_t type_version = read_u32(cache->type_version);
46304627
DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_METHOD);
4631-
int dictoffset = cache->dict_offset;
4628+
int dictoffset = self_cls->tp_dictoffset;
4629+
assert(dictoffset > 0);
46324630
PyObject *dict = *(PyObject **)((char *)self + dictoffset);
4633-
assert(dictoffset == self_cls->tp_dictoffset && dictoffset > 0);
46344631
/* This object has a __dict__, just not yet created */
46354632
DEOPT_IF(dict != NULL, LOAD_METHOD);
46364633
STAT_INC(LOAD_METHOD, hit);

‎Python/specialize.c

Copy file name to clipboardExpand all lines: Python/specialize.c
+3-6Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
986986
}
987987
}
988988
}
989-
if (dictkind == MANAGED_VALUES || dictkind == MANAGED_DICT || dictkind == OFFSET_DICT) {
989+
if (dictkind == MANAGED_VALUES || dictkind == OFFSET_DICT) {
990990
Py_ssize_t index = _PyDictKeys_StringLookup(keys, name);
991991
if (index != DKIX_EMPTY) {
992992
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_LOAD_METHOD_IS_ATTR);
@@ -1007,17 +1007,14 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
10071007
_Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_VALUES);
10081008
break;
10091009
case MANAGED_DICT:
1010-
*(int16_t *)&cache->dict_offset = (int16_t)MANAGED_DICT_OFFSET;
1011-
_Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_DICT);
1012-
break;
1010+
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_LOAD_METHOD_HAS_MANAGED_DICT);
1011+
goto fail;
10131012
case OFFSET_DICT:
10141013
assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX);
1015-
cache->dict_offset = (uint16_t)owner_cls->tp_dictoffset;
10161014
_Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_DICT);
10171015
break;
10181016
case LAZY_DICT:
10191017
assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX);
1020-
cache->dict_offset = (uint16_t)owner_cls->tp_dictoffset;
10211018
_Py_SET_OPCODE(*instr, LOAD_METHOD_LAZY_DICT);
10221019
break;
10231020
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.