Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commitde64e75

Browse files
gh-94673: More Per-Interpreter Fields for Builtin Static Types (gh-103912)
his involves moving tp_dict, tp_bases, and tp_mro to PyInterpreterState, in the same way we did for tp_subclasses. Those three fields are effectively const for builtin static types (unlike tp_subclasses). In theory we only need to make their values immortal, along with their contents. However, that isn't such a simple proposition. (Seegh-103823.) In the meantime the simplest solution is to move the fields into the interpreter.One alternative is to statically allocate the values, but that's its own can of worms.
1 parent872cbc6 commitde64e75

File tree

5 files changed

+185
-86
lines changed

5 files changed

+185
-86
lines changed

‎Include/internal/pycore_typeobject.h‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ struct type_cache {
4444

4545
typedefstruct {
4646
PyTypeObject*type;
47+
intreadying;
48+
intready;
49+
// XXX tp_dict, tp_bases, and tp_mro can probably be statically
50+
// allocated, instead of dynamically and stored on the interpreter.
51+
PyObject*tp_dict;
52+
PyObject*tp_bases;
53+
PyObject*tp_mro;
4754
PyObject*tp_subclasses;
4855
/* We never clean up weakrefs for static builtin types since
4956
they will effectively never get triggered. However, there

‎Modules/_abc.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include"pycore_moduleobject.h"// _PyModule_GetState()
88
#include"pycore_object.h"// _PyType_GetSubclasses()
99
#include"pycore_runtime.h"// _Py_ID()
10+
#include"pycore_typeobject.h"// _PyType_GetMRO()
1011
#include"clinic/_abc.c.h"
1112

1213
/*[clinic input]

‎Modules/gcmodule.c‎

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2174,41 +2174,16 @@ _PyGC_DumpShutdownStats(PyInterpreterState *interp)
21742174
}
21752175

21762176

2177-
staticvoid
2178-
gc_fini_untrack(PyGC_Head*list)
2179-
{
2180-
PyGC_Head*gc;
2181-
for (gc=GC_NEXT(list);gc!=list;gc=GC_NEXT(list)) {
2182-
PyObject*op=FROM_GC(gc);
2183-
_PyObject_GC_UNTRACK(op);
2184-
// gh-92036: If a deallocator function expect the object to be tracked
2185-
// by the GC (ex: func_dealloc()), it can crash if called on an object
2186-
// which is no longer tracked by the GC. Leak one strong reference on
2187-
// purpose so the object is never deleted and its deallocator is not
2188-
// called.
2189-
Py_INCREF(op);
2190-
}
2191-
}
2192-
2193-
21942177
void
21952178
_PyGC_Fini(PyInterpreterState*interp)
21962179
{
21972180
GCState*gcstate=&interp->gc;
21982181
Py_CLEAR(gcstate->garbage);
21992182
Py_CLEAR(gcstate->callbacks);
22002183

2201-
if (!_Py_IsMainInterpreter(interp)) {
2202-
// bpo-46070: Explicitly untrack all objects currently tracked by the
2203-
// GC. Otherwise, if an object is used later by another interpreter,
2204-
// calling PyObject_GC_UnTrack() on the object crashs if the previous
2205-
// or the next object of the PyGC_Head structure became a dangling
2206-
// pointer.
2207-
for (inti=0;i<NUM_GENERATIONS;i++) {
2208-
PyGC_Head*gen=GEN_HEAD(gcstate,i);
2209-
gc_fini_untrack(gen);
2210-
}
2211-
}
2184+
/* We expect that none of this interpreters objects are shared
2185+
with other interpreters.
2186+
See https://github.com/python/cpython/issues/90228. */
22122187
}
22132188

22142189
/* for debugging */

‎Objects/structseq.c‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,6 @@ _PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp,
511511
Py_ssize_tn_members=count_members(desc,&n_unnamed_members);
512512
PyMemberDef*members=NULL;
513513

514-
intinitialized=1;
515514
if ((type->tp_flags&Py_TPFLAGS_READY)==0) {
516515
assert(type->tp_name==NULL);
517516
assert(type->tp_members==NULL);
@@ -524,7 +523,6 @@ _PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp,
524523
initialize_static_fields(type,desc,members,tp_flags);
525524

526525
_Py_SetImmortal(type);
527-
initialized=0;
528526
}
529527
#ifndefNDEBUG
530528
else {
@@ -543,13 +541,10 @@ _PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp,
543541
desc->name);
544542
gotoerror;
545543
}
546-
// This should be dropped if tp_dict is made per-interpreter.
547-
if (initialized) {
548-
return0;
549-
}
550544

551545
if (initialize_structseq_dict(
552-
desc,_PyType_GetDict(type),n_members,n_unnamed_members)<0) {
546+
desc,_PyType_GetDict(type),n_members,n_unnamed_members)<0)
547+
{
553548
gotoerror;
554549
}
555550

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp