mirror of
https://github.com/python/cpython.git
synced 2025-08-23 18:24:46 +00:00
gh-81057: Generate a Separate Initializer For Each Part of the Global Objects Initializer (gh-99389)
Up until now we had a single generated initializer macro for all the statically declared global objects in _PyRuntimeState, including several one-offs (e.g. the empty tuple). The one-offs don't need to be generated, but were because we had one big initializer. Having separate initializers for set of generated global objects allows us to generate only the ones we need to. This allows us to add initializers for one-off global objects without having to generate them. https://github.com/python/cpython/issues/81057
This commit is contained in:
parent
6abec1caff
commit
fe55ff3f68
4 changed files with 1528 additions and 1517 deletions
|
@ -25,6 +25,7 @@ _PyStaticObject_CheckRefcnt(PyObject *obj) {
|
||||||
#ifdef Py_DEBUG
|
#ifdef Py_DEBUG
|
||||||
static inline void
|
static inline void
|
||||||
_PyStaticObjects_CheckRefcnt(void) {
|
_PyStaticObjects_CheckRefcnt(void) {
|
||||||
|
/* generated (see pycore_runtime_init_generated.h) */
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -5]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -5]);
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -4]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -4]);
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -3]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -3]);
|
||||||
|
@ -287,7 +288,6 @@ _PyStaticObjects_CheckRefcnt(void) {
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 254]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 254]);
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 255]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 255]);
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 256]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 256]);
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_empty));
|
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[0]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[0]);
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[1]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[1]);
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[2]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[2]);
|
||||||
|
@ -1469,6 +1469,8 @@ _PyStaticObjects_CheckRefcnt(void) {
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[253 - 128]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[253 - 128]);
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[254 - 128]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[254 - 128]);
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[255 - 128]);
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[255 - 128]);
|
||||||
|
/* non-generated */
|
||||||
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_empty));
|
||||||
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(tuple_empty));
|
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(tuple_empty));
|
||||||
}
|
}
|
||||||
#endif // Py_DEBUG
|
#endif // Py_DEBUG
|
||||||
|
|
|
@ -28,7 +28,22 @@ extern "C" {
|
||||||
until _PyInterpreterState_Enable() is called. */ \
|
until _PyInterpreterState_Enable() is called. */ \
|
||||||
.next_id = -1, \
|
.next_id = -1, \
|
||||||
}, \
|
}, \
|
||||||
.global_objects = _Py_global_objects_INIT, \
|
.global_objects = { \
|
||||||
|
.singletons = { \
|
||||||
|
.small_ints = _Py_small_ints_INIT, \
|
||||||
|
.bytes_empty = _PyBytes_SIMPLE_INIT(0, 0), \
|
||||||
|
.bytes_characters = _Py_bytes_characters_INIT, \
|
||||||
|
.strings = { \
|
||||||
|
.literals = _Py_str_literals_INIT, \
|
||||||
|
.identifiers = _Py_str_identifiers_INIT, \
|
||||||
|
.ascii = _Py_str_ascii_INIT, \
|
||||||
|
.latin1 = _Py_str_latin1_INIT, \
|
||||||
|
}, \
|
||||||
|
.tuple_empty = { \
|
||||||
|
.ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0) \
|
||||||
|
}, \
|
||||||
|
}, \
|
||||||
|
}, \
|
||||||
._main_interpreter = _PyInterpreterState_INIT, \
|
._main_interpreter = _PyInterpreterState_INIT, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
41
Include/internal/pycore_runtime_init_generated.h
generated
41
Include/internal/pycore_runtime_init_generated.h
generated
|
@ -9,9 +9,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The following is auto-generated by Tools/build/generate_global_objects.py. */
|
/* The following is auto-generated by Tools/build/generate_global_objects.py. */
|
||||||
#define _Py_global_objects_INIT { \
|
#define _Py_small_ints_INIT { \
|
||||||
.singletons = { \
|
|
||||||
.small_ints = { \
|
|
||||||
_PyLong_DIGIT_INIT(-5), \
|
_PyLong_DIGIT_INIT(-5), \
|
||||||
_PyLong_DIGIT_INIT(-4), \
|
_PyLong_DIGIT_INIT(-4), \
|
||||||
_PyLong_DIGIT_INIT(-3), \
|
_PyLong_DIGIT_INIT(-3), \
|
||||||
|
@ -274,10 +272,9 @@ extern "C" {
|
||||||
_PyLong_DIGIT_INIT(254), \
|
_PyLong_DIGIT_INIT(254), \
|
||||||
_PyLong_DIGIT_INIT(255), \
|
_PyLong_DIGIT_INIT(255), \
|
||||||
_PyLong_DIGIT_INIT(256), \
|
_PyLong_DIGIT_INIT(256), \
|
||||||
}, \
|
}
|
||||||
\
|
|
||||||
.bytes_empty = _PyBytes_SIMPLE_INIT(0, 0), \
|
#define _Py_bytes_characters_INIT { \
|
||||||
.bytes_characters = { \
|
|
||||||
_PyBytes_CHAR_INIT(0), \
|
_PyBytes_CHAR_INIT(0), \
|
||||||
_PyBytes_CHAR_INIT(1), \
|
_PyBytes_CHAR_INIT(1), \
|
||||||
_PyBytes_CHAR_INIT(2), \
|
_PyBytes_CHAR_INIT(2), \
|
||||||
|
@ -534,10 +531,9 @@ extern "C" {
|
||||||
_PyBytes_CHAR_INIT(253), \
|
_PyBytes_CHAR_INIT(253), \
|
||||||
_PyBytes_CHAR_INIT(254), \
|
_PyBytes_CHAR_INIT(254), \
|
||||||
_PyBytes_CHAR_INIT(255), \
|
_PyBytes_CHAR_INIT(255), \
|
||||||
}, \
|
}
|
||||||
\
|
|
||||||
.strings = { \
|
#define _Py_str_literals_INIT { \
|
||||||
.literals = { \
|
|
||||||
INIT_STR(anon_dictcomp, "<dictcomp>"), \
|
INIT_STR(anon_dictcomp, "<dictcomp>"), \
|
||||||
INIT_STR(anon_genexpr, "<genexpr>"), \
|
INIT_STR(anon_genexpr, "<genexpr>"), \
|
||||||
INIT_STR(anon_lambda, "<lambda>"), \
|
INIT_STR(anon_lambda, "<lambda>"), \
|
||||||
|
@ -560,8 +556,9 @@ extern "C" {
|
||||||
INIT_STR(percent, "%"), \
|
INIT_STR(percent, "%"), \
|
||||||
INIT_STR(shim_name, "<shim>"), \
|
INIT_STR(shim_name, "<shim>"), \
|
||||||
INIT_STR(utf_8, "utf-8"), \
|
INIT_STR(utf_8, "utf-8"), \
|
||||||
}, \
|
}
|
||||||
.identifiers = { \
|
|
||||||
|
#define _Py_str_identifiers_INIT { \
|
||||||
INIT_ID(CANCELLED), \
|
INIT_ID(CANCELLED), \
|
||||||
INIT_ID(FINISHED), \
|
INIT_ID(FINISHED), \
|
||||||
INIT_ID(False), \
|
INIT_ID(False), \
|
||||||
|
@ -1209,8 +1206,9 @@ extern "C" {
|
||||||
INIT_ID(x), \
|
INIT_ID(x), \
|
||||||
INIT_ID(year), \
|
INIT_ID(year), \
|
||||||
INIT_ID(zdict), \
|
INIT_ID(zdict), \
|
||||||
}, \
|
}
|
||||||
.ascii = { \
|
|
||||||
|
#define _Py_str_ascii_INIT { \
|
||||||
_PyASCIIObject_INIT("\x00"), \
|
_PyASCIIObject_INIT("\x00"), \
|
||||||
_PyASCIIObject_INIT("\x01"), \
|
_PyASCIIObject_INIT("\x01"), \
|
||||||
_PyASCIIObject_INIT("\x02"), \
|
_PyASCIIObject_INIT("\x02"), \
|
||||||
|
@ -1339,8 +1337,9 @@ extern "C" {
|
||||||
_PyASCIIObject_INIT("\x7d"), \
|
_PyASCIIObject_INIT("\x7d"), \
|
||||||
_PyASCIIObject_INIT("\x7e"), \
|
_PyASCIIObject_INIT("\x7e"), \
|
||||||
_PyASCIIObject_INIT("\x7f"), \
|
_PyASCIIObject_INIT("\x7f"), \
|
||||||
}, \
|
}
|
||||||
.latin1 = { \
|
|
||||||
|
#define _Py_str_latin1_INIT { \
|
||||||
_PyUnicode_LATIN1_INIT("\x80", "\xc2\x80"), \
|
_PyUnicode_LATIN1_INIT("\x80", "\xc2\x80"), \
|
||||||
_PyUnicode_LATIN1_INIT("\x81", "\xc2\x81"), \
|
_PyUnicode_LATIN1_INIT("\x81", "\xc2\x81"), \
|
||||||
_PyUnicode_LATIN1_INIT("\x82", "\xc2\x82"), \
|
_PyUnicode_LATIN1_INIT("\x82", "\xc2\x82"), \
|
||||||
|
@ -1469,15 +1468,9 @@ extern "C" {
|
||||||
_PyUnicode_LATIN1_INIT("\xfd", "\xc3\xbd"), \
|
_PyUnicode_LATIN1_INIT("\xfd", "\xc3\xbd"), \
|
||||||
_PyUnicode_LATIN1_INIT("\xfe", "\xc3\xbe"), \
|
_PyUnicode_LATIN1_INIT("\xfe", "\xc3\xbe"), \
|
||||||
_PyUnicode_LATIN1_INIT("\xff", "\xc3\xbf"), \
|
_PyUnicode_LATIN1_INIT("\xff", "\xc3\xbf"), \
|
||||||
}, \
|
|
||||||
}, \
|
|
||||||
\
|
|
||||||
.tuple_empty = { \
|
|
||||||
.ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0) \
|
|
||||||
}, \
|
|
||||||
}, \
|
|
||||||
}
|
}
|
||||||
/* End auto-generated code */
|
/* End auto-generated code */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -123,6 +123,12 @@ IDENTIFIERS = [
|
||||||
'__rdivmod__',
|
'__rdivmod__',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
NON_GENERATED_IMMORTAL_OBJECTS = [
|
||||||
|
# The generated ones come from generate_runtime_init().
|
||||||
|
'(PyObject *)&_Py_SINGLETON(bytes_empty)',
|
||||||
|
'(PyObject *)&_Py_SINGLETON(tuple_empty)',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# helpers
|
# helpers
|
||||||
|
@ -287,38 +293,33 @@ def generate_runtime_init(identifiers, strings):
|
||||||
printer = Printer(outfile)
|
printer = Printer(outfile)
|
||||||
printer.write(before)
|
printer.write(before)
|
||||||
printer.write(START)
|
printer.write(START)
|
||||||
with printer.block('#define _Py_global_objects_INIT', continuation=True):
|
with printer.block('#define _Py_small_ints_INIT', continuation=True):
|
||||||
with printer.block('.singletons =', ','):
|
|
||||||
# Global int objects.
|
|
||||||
with printer.block('.small_ints =', ','):
|
|
||||||
for i in range(-nsmallnegints, nsmallposints):
|
for i in range(-nsmallnegints, nsmallposints):
|
||||||
printer.write(f'_PyLong_DIGIT_INIT({i}),')
|
printer.write(f'_PyLong_DIGIT_INIT({i}),')
|
||||||
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + {i}]')
|
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + {i}]')
|
||||||
printer.write('')
|
printer.write('')
|
||||||
# Global bytes objects.
|
with printer.block('#define _Py_bytes_characters_INIT', continuation=True):
|
||||||
printer.write('.bytes_empty = _PyBytes_SIMPLE_INIT(0, 0),')
|
|
||||||
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(bytes_empty)')
|
|
||||||
with printer.block('.bytes_characters =', ','):
|
|
||||||
for i in range(256):
|
for i in range(256):
|
||||||
printer.write(f'_PyBytes_CHAR_INIT({i}),')
|
printer.write(f'_PyBytes_CHAR_INIT({i}),')
|
||||||
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(bytes_characters)[{i}]')
|
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(bytes_characters)[{i}]')
|
||||||
printer.write('')
|
printer.write('')
|
||||||
# Global strings.
|
with printer.block('#define _Py_str_literals_INIT', continuation=True):
|
||||||
with printer.block('.strings =', ','):
|
|
||||||
with printer.block('.literals =', ','):
|
|
||||||
for literal, name in sorted(strings.items(), key=lambda x: x[1]):
|
for literal, name in sorted(strings.items(), key=lambda x: x[1]):
|
||||||
printer.write(f'INIT_STR({name}, "{literal}"),')
|
printer.write(f'INIT_STR({name}, "{literal}"),')
|
||||||
immortal_objects.append(f'(PyObject *)&_Py_STR({name})')
|
immortal_objects.append(f'(PyObject *)&_Py_STR({name})')
|
||||||
with printer.block('.identifiers =', ','):
|
printer.write('')
|
||||||
|
with printer.block('#define _Py_str_identifiers_INIT', continuation=True):
|
||||||
for name in sorted(identifiers):
|
for name in sorted(identifiers):
|
||||||
assert name.isidentifier(), name
|
assert name.isidentifier(), name
|
||||||
printer.write(f'INIT_ID({name}),')
|
printer.write(f'INIT_ID({name}),')
|
||||||
immortal_objects.append(f'(PyObject *)&_Py_ID({name})')
|
immortal_objects.append(f'(PyObject *)&_Py_ID({name})')
|
||||||
with printer.block('.ascii =', ','):
|
printer.write('')
|
||||||
|
with printer.block('#define _Py_str_ascii_INIT', continuation=True):
|
||||||
for i in range(128):
|
for i in range(128):
|
||||||
printer.write(f'_PyASCIIObject_INIT("\\x{i:02x}"),')
|
printer.write(f'_PyASCIIObject_INIT("\\x{i:02x}"),')
|
||||||
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).ascii[{i}]')
|
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).ascii[{i}]')
|
||||||
with printer.block('.latin1 =', ','):
|
printer.write('')
|
||||||
|
with printer.block('#define _Py_str_latin1_INIT', continuation=True):
|
||||||
for i in range(128, 256):
|
for i in range(128, 256):
|
||||||
utf8 = ['"']
|
utf8 = ['"']
|
||||||
for c in chr(i).encode('utf-8'):
|
for c in chr(i).encode('utf-8'):
|
||||||
|
@ -326,10 +327,6 @@ def generate_runtime_init(identifiers, strings):
|
||||||
utf8.append('"')
|
utf8.append('"')
|
||||||
printer.write(f'_PyUnicode_LATIN1_INIT("\\x{i:02x}", {"".join(utf8)}),')
|
printer.write(f'_PyUnicode_LATIN1_INIT("\\x{i:02x}", {"".join(utf8)}),')
|
||||||
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).latin1[{i} - 128]')
|
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).latin1[{i} - 128]')
|
||||||
printer.write('')
|
|
||||||
with printer.block('.tuple_empty =', ','):
|
|
||||||
printer.write('.ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0)')
|
|
||||||
immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(tuple_empty)')
|
|
||||||
printer.write(END)
|
printer.write(END)
|
||||||
printer.write(after)
|
printer.write(after)
|
||||||
return immortal_objects
|
return immortal_objects
|
||||||
|
@ -366,7 +363,7 @@ def generate_static_strings_initializer(identifiers, strings):
|
||||||
printer.write(after)
|
printer.write(after)
|
||||||
|
|
||||||
|
|
||||||
def generate_global_object_finalizers(immortal_objects):
|
def generate_global_object_finalizers(generated_immortal_objects):
|
||||||
# Target the runtime initializer.
|
# Target the runtime initializer.
|
||||||
filename = os.path.join(INTERNAL, 'pycore_global_objects_fini_generated.h')
|
filename = os.path.join(INTERNAL, 'pycore_global_objects_fini_generated.h')
|
||||||
|
|
||||||
|
@ -387,8 +384,12 @@ def generate_global_object_finalizers(immortal_objects):
|
||||||
printer.write('#ifdef Py_DEBUG')
|
printer.write('#ifdef Py_DEBUG')
|
||||||
printer.write("static inline void")
|
printer.write("static inline void")
|
||||||
with printer.block("_PyStaticObjects_CheckRefcnt(void)"):
|
with printer.block("_PyStaticObjects_CheckRefcnt(void)"):
|
||||||
for i in immortal_objects:
|
printer.write('/* generated (see pycore_runtime_init_generated.h) */')
|
||||||
printer.write(f'_PyStaticObject_CheckRefcnt({i});')
|
for ref in generated_immortal_objects:
|
||||||
|
printer.write(f'_PyStaticObject_CheckRefcnt({ref});')
|
||||||
|
printer.write('/* non-generated */')
|
||||||
|
for ref in NON_GENERATED_IMMORTAL_OBJECTS:
|
||||||
|
printer.write(f'_PyStaticObject_CheckRefcnt({ref});')
|
||||||
printer.write('#endif // Py_DEBUG')
|
printer.write('#endif // Py_DEBUG')
|
||||||
printer.write(END)
|
printer.write(END)
|
||||||
printer.write(after)
|
printer.write(after)
|
||||||
|
@ -416,9 +417,9 @@ def main() -> None:
|
||||||
identifiers, strings = get_identifiers_and_strings()
|
identifiers, strings = get_identifiers_and_strings()
|
||||||
|
|
||||||
generate_global_strings(identifiers, strings)
|
generate_global_strings(identifiers, strings)
|
||||||
immortal_objects = generate_runtime_init(identifiers, strings)
|
generated_immortal_objects = generate_runtime_init(identifiers, strings)
|
||||||
generate_static_strings_initializer(identifiers, strings)
|
generate_static_strings_initializer(identifiers, strings)
|
||||||
generate_global_object_finalizers(immortal_objects)
|
generate_global_object_finalizers(generated_immortal_objects)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue