mirror of
https://github.com/python/cpython.git
synced 2025-07-19 17:25:54 +00:00
bpo-46765: Replace Locally Cached Strings with Statically Initialized Objects (gh-31366)
https://bugs.python.org/issue46765
This commit is contained in:
parent
cff4d5c5d2
commit
1f455361ec
22 changed files with 192 additions and 526 deletions
|
@ -768,25 +768,6 @@ warn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message,
|
|||
static int
|
||||
is_internal_frame(PyFrameObject *frame)
|
||||
{
|
||||
static PyObject *importlib_string = NULL;
|
||||
static PyObject *bootstrap_string = NULL;
|
||||
int contains;
|
||||
|
||||
if (importlib_string == NULL) {
|
||||
importlib_string = PyUnicode_FromString("importlib");
|
||||
if (importlib_string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bootstrap_string = PyUnicode_FromString("_bootstrap");
|
||||
if (bootstrap_string == NULL) {
|
||||
Py_DECREF(importlib_string);
|
||||
return 0;
|
||||
}
|
||||
Py_INCREF(importlib_string);
|
||||
Py_INCREF(bootstrap_string);
|
||||
}
|
||||
|
||||
if (frame == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -802,12 +783,12 @@ is_internal_frame(PyFrameObject *frame)
|
|||
return 0;
|
||||
}
|
||||
|
||||
contains = PyUnicode_Contains(filename, importlib_string);
|
||||
int contains = PyUnicode_Contains(filename, &_Py_ID(importlib));
|
||||
if (contains < 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (contains > 0) {
|
||||
contains = PyUnicode_Contains(filename, bootstrap_string);
|
||||
contains = PyUnicode_Contains(filename, &_Py_ID(_bootstrap));
|
||||
if (contains < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "Python.h"
|
||||
#include "pycore_ast.h" // expr_ty
|
||||
#include "pycore_runtime.h" // _Py_ID()
|
||||
#include <float.h> // DBL_MAX_10_EXP
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -8,11 +9,10 @@
|
|||
* See ast.unparse for a full unparser (written in Python)
|
||||
*/
|
||||
|
||||
static PyObject *_str_open_br;
|
||||
static PyObject *_str_dbl_open_br;
|
||||
static PyObject *_str_close_br;
|
||||
static PyObject *_str_dbl_close_br;
|
||||
static PyObject *_str_inf;
|
||||
_Py_DECLARE_STR(open_br, "{");
|
||||
_Py_DECLARE_STR(dbl_open_br, "{{");
|
||||
_Py_DECLARE_STR(close_br, "}");
|
||||
_Py_DECLARE_STR(dbl_close_br, "}}");
|
||||
static PyObject *_str_replace_inf;
|
||||
|
||||
/* Forward declarations for recursion via helper functions. */
|
||||
|
@ -80,7 +80,7 @@ append_repr(_PyUnicodeWriter *writer, PyObject *obj)
|
|||
{
|
||||
PyObject *new_repr = PyUnicode_Replace(
|
||||
repr,
|
||||
_str_inf,
|
||||
&_Py_ID(inf),
|
||||
_str_replace_inf,
|
||||
-1
|
||||
);
|
||||
|
@ -575,11 +575,11 @@ escape_braces(PyObject *orig)
|
|||
{
|
||||
PyObject *temp;
|
||||
PyObject *result;
|
||||
temp = PyUnicode_Replace(orig, _str_open_br, _str_dbl_open_br, -1);
|
||||
temp = PyUnicode_Replace(orig, &_Py_STR(open_br), &_Py_STR(dbl_open_br), -1);
|
||||
if (!temp) {
|
||||
return NULL;
|
||||
}
|
||||
result = PyUnicode_Replace(temp, _str_close_br, _str_dbl_close_br, -1);
|
||||
result = PyUnicode_Replace(temp, &_Py_STR(close_br), &_Py_STR(dbl_close_br), -1);
|
||||
Py_DECREF(temp);
|
||||
return result;
|
||||
}
|
||||
|
@ -673,7 +673,7 @@ append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e)
|
|||
if (!temp_fv_str) {
|
||||
return -1;
|
||||
}
|
||||
if (PyUnicode_Find(temp_fv_str, _str_open_br, 0, 1, 1) == 0) {
|
||||
if (PyUnicode_Find(temp_fv_str, &_Py_STR(open_br), 0, 1, 1) == 0) {
|
||||
/* Expression starts with a brace, split it with a space from the outer
|
||||
one. */
|
||||
outer_brace = "{ ";
|
||||
|
@ -927,26 +927,6 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
|
|||
static int
|
||||
maybe_init_static_strings(void)
|
||||
{
|
||||
if (!_str_open_br &&
|
||||
!(_str_open_br = PyUnicode_InternFromString("{"))) {
|
||||
return -1;
|
||||
}
|
||||
if (!_str_dbl_open_br &&
|
||||
!(_str_dbl_open_br = PyUnicode_InternFromString("{{"))) {
|
||||
return -1;
|
||||
}
|
||||
if (!_str_close_br &&
|
||||
!(_str_close_br = PyUnicode_InternFromString("}"))) {
|
||||
return -1;
|
||||
}
|
||||
if (!_str_dbl_close_br &&
|
||||
!(_str_dbl_close_br = PyUnicode_InternFromString("}}"))) {
|
||||
return -1;
|
||||
}
|
||||
if (!_str_inf &&
|
||||
!(_str_inf = PyUnicode_FromString("inf"))) {
|
||||
return -1;
|
||||
}
|
||||
if (!_str_replace_inf &&
|
||||
!(_str_replace_inf = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP))) {
|
||||
return -1;
|
||||
|
|
|
@ -2522,7 +2522,6 @@ static int
|
|||
compiler_class(struct compiler *c, stmt_ty s)
|
||||
{
|
||||
PyCodeObject *co;
|
||||
PyObject *str;
|
||||
int i, firstlineno;
|
||||
asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
|
||||
|
||||
|
@ -2557,30 +2556,21 @@ compiler_class(struct compiler *c, stmt_ty s)
|
|||
Py_INCREF(s->v.ClassDef.name);
|
||||
Py_XSETREF(c->u->u_private, s->v.ClassDef.name);
|
||||
/* load (global) __name__ ... */
|
||||
str = PyUnicode_InternFromString("__name__");
|
||||
if (!str || !compiler_nameop(c, str, Load)) {
|
||||
Py_XDECREF(str);
|
||||
if (!compiler_nameop(c, &_Py_ID(__name__), Load)) {
|
||||
compiler_exit_scope(c);
|
||||
return 0;
|
||||
}
|
||||
Py_DECREF(str);
|
||||
/* ... and store it as __module__ */
|
||||
str = PyUnicode_InternFromString("__module__");
|
||||
if (!str || !compiler_nameop(c, str, Store)) {
|
||||
Py_XDECREF(str);
|
||||
if (!compiler_nameop(c, &_Py_ID(__module__), Store)) {
|
||||
compiler_exit_scope(c);
|
||||
return 0;
|
||||
}
|
||||
Py_DECREF(str);
|
||||
assert(c->u->u_qualname);
|
||||
ADDOP_LOAD_CONST(c, c->u->u_qualname);
|
||||
str = PyUnicode_InternFromString("__qualname__");
|
||||
if (!str || !compiler_nameop(c, str, Store)) {
|
||||
Py_XDECREF(str);
|
||||
if (!compiler_nameop(c, &_Py_ID(__qualname__), Store)) {
|
||||
compiler_exit_scope(c);
|
||||
return 0;
|
||||
}
|
||||
Py_DECREF(str);
|
||||
/* compile the body proper */
|
||||
if (!compiler_body(c, s->v.ClassDef.body)) {
|
||||
compiler_exit_scope(c);
|
||||
|
@ -2591,13 +2581,7 @@ compiler_class(struct compiler *c, stmt_ty s)
|
|||
/* Return __classcell__ if it is referenced, otherwise return None */
|
||||
if (c->u->u_ste->ste_needs_class_closure) {
|
||||
/* Store __classcell__ into class namespace & return it */
|
||||
str = PyUnicode_InternFromString("__class__");
|
||||
if (str == NULL) {
|
||||
compiler_exit_scope(c);
|
||||
return 0;
|
||||
}
|
||||
i = compiler_lookup_arg(c->u->u_cellvars, str);
|
||||
Py_DECREF(str);
|
||||
i = compiler_lookup_arg(c->u->u_cellvars, &_Py_ID(__class__));
|
||||
if (i < 0) {
|
||||
compiler_exit_scope(c);
|
||||
return 0;
|
||||
|
@ -2606,13 +2590,10 @@ compiler_class(struct compiler *c, stmt_ty s)
|
|||
|
||||
ADDOP_I(c, LOAD_CLOSURE, i);
|
||||
ADDOP_I(c, COPY, 1);
|
||||
str = PyUnicode_InternFromString("__classcell__");
|
||||
if (!str || !compiler_nameop(c, str, Store)) {
|
||||
Py_XDECREF(str);
|
||||
if (!compiler_nameop(c, &_Py_ID(__classcell__), Store)) {
|
||||
compiler_exit_scope(c);
|
||||
return 0;
|
||||
}
|
||||
Py_DECREF(str);
|
||||
}
|
||||
else {
|
||||
/* No methods referenced __class__, so just return None */
|
||||
|
@ -4741,13 +4722,8 @@ compiler_joined_str(struct compiler *c, expr_ty e)
|
|||
|
||||
Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
|
||||
if (value_count > STACK_USE_GUIDELINE) {
|
||||
ADDOP_LOAD_CONST_NEW(c, _PyUnicode_FromASCII("", 0));
|
||||
PyObject *join = _PyUnicode_FromASCII("join", 4);
|
||||
if (join == NULL) {
|
||||
return 0;
|
||||
}
|
||||
ADDOP_NAME(c, LOAD_METHOD, join, names);
|
||||
Py_DECREF(join);
|
||||
ADDOP_LOAD_CONST_NEW(c, &_Py_STR(empty));
|
||||
ADDOP_NAME(c, LOAD_METHOD, &_Py_ID(join), names);
|
||||
ADDOP_I(c, BUILD_LIST, 0);
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
|
||||
VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "pycore_runtime.h" // _Py_ID()
|
||||
#include "pycore_runtime_init.h" // _PyRuntimeState_INIT
|
||||
#include "pycore_sliceobject.h" // _PySlice_Fini()
|
||||
#include "pycore_symtable.h" // _PySymtable_Fini()
|
||||
#include "pycore_sysmodule.h" // _PySys_ClearAuditHooks()
|
||||
#include "pycore_traceback.h" // _Py_DumpTracebackThreads()
|
||||
#include "pycore_tuple.h" // _PyTuple_InitTypes()
|
||||
|
@ -1690,9 +1689,6 @@ finalize_interp_clear(PyThreadState *tstate)
|
|||
int is_main_interp = _Py_IsMainInterpreter(tstate->interp);
|
||||
|
||||
_PyExc_ClearExceptionGroupType(tstate->interp);
|
||||
if (is_main_interp) {
|
||||
_PySymtable_Fini();
|
||||
}
|
||||
|
||||
/* Clear interpreter state and all thread states */
|
||||
_PyInterpreterState_Clear(tstate);
|
||||
|
|
|
@ -230,13 +230,6 @@ static int symtable_raise_if_annotation_block(struct symtable *st, const char *,
|
|||
static int symtable_raise_if_comprehension_block(struct symtable *st, expr_ty);
|
||||
|
||||
|
||||
static identifier top = NULL, lambda = NULL, genexpr = NULL,
|
||||
listcomp = NULL, setcomp = NULL, dictcomp = NULL,
|
||||
__class__ = NULL, _annotation = NULL;
|
||||
|
||||
#define GET_IDENTIFIER(VAR) \
|
||||
((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR)))
|
||||
|
||||
#define DUPLICATE_ARGUMENT \
|
||||
"duplicate argument '%U' in function definition"
|
||||
|
||||
|
@ -313,8 +306,7 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future)
|
|||
recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit;
|
||||
|
||||
/* Make the initial symbol information gathering pass */
|
||||
if (!GET_IDENTIFIER(top) ||
|
||||
!symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0, 0, 0)) {
|
||||
if (!symtable_enter_block(st, &_Py_ID(top), ModuleBlock, (void *)mod, 0, 0, 0, 0)) {
|
||||
_PySymtable_Free(st);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -619,9 +611,7 @@ static int
|
|||
drop_class_free(PySTEntryObject *ste, PyObject *free)
|
||||
{
|
||||
int res;
|
||||
if (!GET_IDENTIFIER(__class__))
|
||||
return 0;
|
||||
res = PySet_Discard(free, __class__);
|
||||
res = PySet_Discard(free, &_Py_ID(__class__));
|
||||
if (res < 0)
|
||||
return 0;
|
||||
if (res)
|
||||
|
@ -834,9 +824,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
|
|||
}
|
||||
else {
|
||||
/* Special-case __class__ */
|
||||
if (!GET_IDENTIFIER(__class__))
|
||||
goto error;
|
||||
if (PySet_Add(newbound, __class__) < 0)
|
||||
if (PySet_Add(newbound, &_Py_ID(__class__)) < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -1610,13 +1598,11 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
|||
VISIT(st, expr, e->v.UnaryOp.operand);
|
||||
break;
|
||||
case Lambda_kind: {
|
||||
if (!GET_IDENTIFIER(lambda))
|
||||
VISIT_QUIT(st, 0);
|
||||
if (e->v.Lambda.args->defaults)
|
||||
VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
|
||||
if (e->v.Lambda.args->kw_defaults)
|
||||
VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults);
|
||||
if (!symtable_enter_block(st, lambda,
|
||||
if (!symtable_enter_block(st, &_Py_ID(lambda),
|
||||
FunctionBlock, (void *)e,
|
||||
e->lineno, e->col_offset,
|
||||
e->end_lineno, e->end_col_offset))
|
||||
|
@ -1730,8 +1716,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
|||
if (e->v.Name.ctx == Load &&
|
||||
st->st_cur->ste_type == FunctionBlock &&
|
||||
_PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) {
|
||||
if (!GET_IDENTIFIER(__class__) ||
|
||||
!symtable_add_def(st, __class__, USE, LOCATION(e)))
|
||||
if (!symtable_add_def(st, &_Py_ID(__class__), USE, LOCATION(e)))
|
||||
VISIT_QUIT(st, 0);
|
||||
}
|
||||
break;
|
||||
|
@ -1832,7 +1817,7 @@ symtable_visit_annotation(struct symtable *st, expr_ty annotation)
|
|||
{
|
||||
int future_annotations = st->st_future->ff_features & CO_FUTURE_ANNOTATIONS;
|
||||
if (future_annotations &&
|
||||
!symtable_enter_block(st, GET_IDENTIFIER(_annotation), AnnotationBlock,
|
||||
!symtable_enter_block(st, &_Py_ID(_annotation), AnnotationBlock,
|
||||
(void *)annotation, annotation->lineno,
|
||||
annotation->col_offset, annotation->end_lineno,
|
||||
annotation->end_col_offset)) {
|
||||
|
@ -1867,7 +1852,7 @@ symtable_visit_annotations(struct symtable *st, stmt_ty o, arguments_ty a, expr_
|
|||
{
|
||||
int future_annotations = st->st_future->ff_features & CO_FUTURE_ANNOTATIONS;
|
||||
if (future_annotations &&
|
||||
!symtable_enter_block(st, GET_IDENTIFIER(_annotation), AnnotationBlock,
|
||||
!symtable_enter_block(st, &_Py_ID(_annotation), AnnotationBlock,
|
||||
(void *)o, o->lineno, o->col_offset, o->end_lineno,
|
||||
o->end_col_offset)) {
|
||||
VISIT_QUIT(st, 0);
|
||||
|
@ -2085,7 +2070,7 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e,
|
|||
static int
|
||||
symtable_visit_genexp(struct symtable *st, expr_ty e)
|
||||
{
|
||||
return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr),
|
||||
return symtable_handle_comprehension(st, e, &_Py_ID(genexpr),
|
||||
e->v.GeneratorExp.generators,
|
||||
e->v.GeneratorExp.elt, NULL);
|
||||
}
|
||||
|
@ -2093,7 +2078,7 @@ symtable_visit_genexp(struct symtable *st, expr_ty e)
|
|||
static int
|
||||
symtable_visit_listcomp(struct symtable *st, expr_ty e)
|
||||
{
|
||||
return symtable_handle_comprehension(st, e, GET_IDENTIFIER(listcomp),
|
||||
return symtable_handle_comprehension(st, e, &_Py_ID(listcomp),
|
||||
e->v.ListComp.generators,
|
||||
e->v.ListComp.elt, NULL);
|
||||
}
|
||||
|
@ -2101,7 +2086,7 @@ symtable_visit_listcomp(struct symtable *st, expr_ty e)
|
|||
static int
|
||||
symtable_visit_setcomp(struct symtable *st, expr_ty e)
|
||||
{
|
||||
return symtable_handle_comprehension(st, e, GET_IDENTIFIER(setcomp),
|
||||
return symtable_handle_comprehension(st, e, &_Py_ID(setcomp),
|
||||
e->v.SetComp.generators,
|
||||
e->v.SetComp.elt, NULL);
|
||||
}
|
||||
|
@ -2109,7 +2094,7 @@ symtable_visit_setcomp(struct symtable *st, expr_ty e)
|
|||
static int
|
||||
symtable_visit_dictcomp(struct symtable *st, expr_ty e)
|
||||
{
|
||||
return symtable_handle_comprehension(st, e, GET_IDENTIFIER(dictcomp),
|
||||
return symtable_handle_comprehension(st, e, &_Py_ID(dictcomp),
|
||||
e->v.DictComp.generators,
|
||||
e->v.DictComp.key,
|
||||
e->v.DictComp.value);
|
||||
|
@ -2173,16 +2158,3 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename,
|
|||
_PyArena_Free(arena);
|
||||
return st;
|
||||
}
|
||||
|
||||
void
|
||||
_PySymtable_Fini(void)
|
||||
{
|
||||
Py_CLEAR(top);
|
||||
Py_CLEAR(lambda);
|
||||
Py_CLEAR(genexpr);
|
||||
Py_CLEAR(listcomp);
|
||||
Py_CLEAR(setcomp);
|
||||
Py_CLEAR(dictcomp);
|
||||
Py_CLEAR(__class__);
|
||||
Py_CLEAR(_annotation);
|
||||
}
|
||||
|
|
|
@ -706,7 +706,6 @@ sys_displayhook(PyObject *module, PyObject *o)
|
|||
{
|
||||
PyObject *outf;
|
||||
PyObject *builtins;
|
||||
static PyObject *newline = NULL;
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
||||
builtins = PyImport_GetModule(&_Py_ID(builtins));
|
||||
|
@ -747,12 +746,8 @@ sys_displayhook(PyObject *module, PyObject *o)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
if (newline == NULL) {
|
||||
newline = PyUnicode_FromString("\n");
|
||||
if (newline == NULL)
|
||||
return NULL;
|
||||
}
|
||||
if (PyFile_WriteObject(newline, outf, Py_PRINT_RAW) != 0)
|
||||
_Py_DECLARE_STR(newline, "\n");
|
||||
if (PyFile_WriteObject(&_Py_STR(newline), outf, Py_PRINT_RAW) != 0)
|
||||
return NULL;
|
||||
if (PyObject_SetAttr(builtins, &_Py_ID(_), o) != 0)
|
||||
return NULL;
|
||||
|
@ -946,30 +941,18 @@ sys_intern_impl(PyObject *module, PyObject *s)
|
|||
|
||||
/*
|
||||
* Cached interned string objects used for calling the profile and
|
||||
* trace functions. Initialized by trace_init().
|
||||
* trace functions.
|
||||
*/
|
||||
static PyObject *whatstrings[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||
|
||||
static int
|
||||
trace_init(void)
|
||||
{
|
||||
static const char * const whatnames[8] = {
|
||||
"call", "exception", "line", "return",
|
||||
"c_call", "c_exception", "c_return",
|
||||
"opcode"
|
||||
};
|
||||
PyObject *name;
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
if (whatstrings[i] == NULL) {
|
||||
name = PyUnicode_InternFromString(whatnames[i]);
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
whatstrings[i] = name;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static PyObject *whatstrings[8] = {
|
||||
&_Py_ID(call),
|
||||
&_Py_ID(exception),
|
||||
&_Py_ID(line),
|
||||
&_Py_ID(return),
|
||||
&_Py_ID(c_call),
|
||||
&_Py_ID(c_exception),
|
||||
&_Py_ID(c_return),
|
||||
&_Py_ID(opcode),
|
||||
};
|
||||
|
||||
|
||||
static PyObject *
|
||||
|
@ -1050,10 +1033,6 @@ trace_trampoline(PyObject *self, PyFrameObject *frame,
|
|||
static PyObject *
|
||||
sys_settrace(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (trace_init() == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
if (args == Py_None) {
|
||||
if (_PyEval_SetTrace(tstate, NULL, NULL) < 0) {
|
||||
|
@ -1099,10 +1078,6 @@ sys_gettrace_impl(PyObject *module)
|
|||
static PyObject *
|
||||
sys_setprofile(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (trace_init() == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
if (args == Py_None) {
|
||||
if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue