8000 Merge branch 'main' into speedup-posixpath.abspath · python/cpython@b127f05 · GitHub
[go: up one dir, main page]

Skip to content

Commit b127f05

Browse files
committed
Merge branch 'main' into speedup-posixpath.abspath
2 parents b7f9df6 + 09c2947 commit b127f05

39 files changed

+718
-368
lines changed

Include/cpython/dictobject.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) {
5656
PyDictObject *mp;
5757
assert(PyDict_Check(op));
5858
mp = _Py_CAST(PyDictObject*, op);
59+
#ifdef Py_GIL_DISABLED
60+
return _Py_atomic_load_ssize_relaxed(&mp->ma_used);
61+
#else
5962
return mp->ma_used;
63+
#endif
6064
}
6165
#define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op))
6266

Include/internal/pycore_ceval.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,12 @@ extern void _PyEval_SignalReceived(void);
4848
#define _Py_PENDING_MAINTHREADONLY 1
4949
#define _Py_PENDING_RAWFREE 2
5050

51+
typedef int _Py_add_pending_call_result;
52+
#define _Py_ADD_PENDING_SUCCESS 0
53+
#define _Py_ADD_PENDING_FULL -1
54+
5155
// Export for '_testinternalcapi' shared extension
52-
PyAPI_FUNC(int) _PyEval_AddPendingCall(
56+
PyAPI_FUNC(_Py_add_pending_call_result) _PyEval_AddPendingCall(
5357
PyInterpreterState *interp,
5458
_Py_pending_call_func func,
5559
void *arg,
@@ -182,7 +186,7 @@ static inline void _Py_LeaveRecursiveCall(void) {
182186

183187
extern struct _PyInterpreterFrame* _PyEval_GetFrame(void);
184188

185-
extern PyObject* _Py_MakeCoro(PyFunctionObject *func);
189+
PyAPI_FUNC(PyObject *)_Py_MakeCoro(PyFunctionObject *func);
186190

187191
/* Handle signals, pending calls, GIL drop request
188192
and asynchronous exception */

Include/internal/pycore_ceval_state.h

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,56 @@ extern "C" {
1414

1515
typedef int (*_Py_pending_call_func)(void *);
1616

17+
struct _pending_call {
18+
_Py_pending_call_func func;
19+
void *arg;
20+
int flags;
21+
};
22+
23+
#define PENDINGCALLSARRAYSIZE 32
24+
25+
#define MAXPENDINGCALLS PENDINGCALLSARRAYSIZE
26+
/* For interpreter-level pending calls, we want to avoid spending too
27+
much time on pending calls in any one thread, so we apply a limit. */
28+
#if MAXPENDINGCALLS > 100
29+
# define MAXPENDINGCALLSLOOP 100
30+
#else
31+
# define MAXPENDINGCALLSLOOP MAXPENDINGCALLS
32+
#endif
33+
34+
#define MAXPENDINGCALLS_MAIN PENDINGCALLSARRAYSIZE
35+
/* For the main thread, we want to make sure all pending calls are
36+
run at once, for the sake of prompt signal handling. This is
37+
unlikely to cause any problems since there should be very few
38+
pending calls for the main thread. */
39+
#define MAXPENDINGCALLSLOOP_MAIN 0
40+
1741
struct _pending_calls {
1842
int busy;
1943
PyMutex mutex;
2044
/* Request for running pending calls. */
21-
int32_t calls_to_do;
22-
#define NPENDINGCALLS 32
23-
struct _pending_call {
24-
_Py_pending_call_func func;
25-
void *arg;
26-
int flags;
27-
} calls[NPENDINGCALLS];
45+
int32_t npending;
46+
/* The maximum allowed number of pending calls.
47+
If the queue fills up to this point then _PyEval_AddPendingCall()
48+
will return _Py_ADD_PENDING_FULL. */
49+
int32_t max;
50+
/* We don't want a flood of pending calls to interrupt any one thread
51+
for too long, so we keep a limit on the number handled per pass.
52+
A value of 0 means there is no limit (other than the maximum
53+
size of the list of pending calls). */
54+
int32_t maxloop;
55+
struct _pending_call calls[PENDINGCALLSARRAYSIZE];
2856
int first;
29-
int last;
57+
int next;
3058
};
3159

60+
3261
typedef enum {
3362
PERF_STATUS_FAILED = -1, // Perf trampoline is in an invalid state
3463
PERF_STATUS_NO_INIT = 0, // Perf trampoline is not initialized
3564
PERF_STATUS_OK = 1, // Perf trampoline is ready to be executed
3665
} perf_status_t;
3766

38-
3967
#ifdef PY_HAVE_PERF_TRAMPOLINE
4068
struct code_arena_st;
4169

@@ -48,6 +76,7 @@ struct trampoline_api_st {
4876
};
4977
#endif
5078

79+
5180
struct _ceval_runtime_state {
5281
struct {
5382
#ifdef PY_HAVE_PERF_TRAMPOLINE
@@ -62,10 +91,15 @@ struct _ceval_runtime_state {
6291
#endif
6392
} perf;
6493
/* Pending calls to be made only on the main thread. */
94+
// The signal machinery falls back on this
95+
// so it must be especially stable and efficient.
96+
// For example, we use a preallocated array
97+
// for the list of pending calls.
6598
struct _pending_calls pending_mainthread;
6699
PyMutex sys_trace_profile_mutex;
67100
};
68101

102+
69103
#ifdef PY_HAVE_PERF_TRAMPOLINE
70104
# define _PyEval_RUNTIME_PERF_INIT \
71105
{ \

Include/internal/pycore_frame.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,17 @@ _PyFrame_NumSlotsForCodeObject(PyCodeObject *code)
110110
return code->co_framesize - FRAME_SPECIALS_SIZE;
111111
}
112112

113-
void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest);
113+
static inline void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest)
114+
{
115+
assert(src->stacktop >= _PyFrame_GetCode(src)->co_nlocalsplus);
116+
*dest = *src;
117+
for (int i = 1; i < src->stacktop; i++) {
118+
dest->localsplus[i] = src->localsplus[i];
119+
}
120+
// Don't leave a dangling pointer to the old frame when creating generators
121+
// and coroutines:
122+
dest->previous = NULL;
123+
}
114124

115125
/* Consumes reference to func and locals.
116126
Does not initialize frame->previous, which happens
@@ -256,7 +266,7 @@ _PyThreadState_HasStackSpace(PyThreadState *tstate, int size)
256266
extern _PyInterpreterFrame *
257267
_PyThreadState_PushFrame(PyThreadState *tstate, size_t size);
258268

259-
void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
269+
PyAPI_FUNC(void) _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
260270

261271
/* Pushes a frame without checking for space.
262272
* Must be guarded by _PyThreadState_HasStackSpace()

Include/internal/pycore_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ static inline PyDictObject *
688688
_PyObject_GetManagedDict(PyObject *obj)
689689
{
690690
PyManagedDictPointer *dorv = _PyObject_ManagedDictPointer(obj);
691-
return (PyDictObject *)FT_ATOMIC_LOAD_PTR_RELAXED(dorv->dict);
691+
return (PyDictObject *)FT_ATOMIC_LOAD_PTR_ACQUIRE(dorv->dict);
692692
}
693693

694694
static inline PyDictValues *

Include/internal/pycore_opcode_metadata.h

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_runtime_init.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ extern PyTypeObject _PyExc_MemoryError;
114114
.autoTSSkey = Py_tss_NEEDS_INIT, \
115115
.parser = _parser_runtime_state_INIT, \
116116
.ceval = { \
117+
.pending_mainthread = { \
118+
.max = MAXPENDINGCALLS_MAIN, \
119+
.maxloop = MAXPENDINGCALLSLOOP_MAIN, \
120+
}, \
117121
.perf = _PyEval_RUNTIME_PERF_INIT, \
118122
}, \
119123
.gilstate = { \
@@ -166,6 +170,10 @@ extern PyTypeObject _PyExc_MemoryError;
166170
.imports = IMPORTS_INIT, \
167171
.ceval = { \
168172
.recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \
173+
.pending = { \
174+
.max = MAXPENDINGCALLS, \
175+
.maxloop = MAXPENDINGCALLSLOOP, \
176+
}, \
169177
}, \
170178
.gc = { \
171179
.enabled = 1, \

Include/internal/pycore_typeobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ extern PyObject * _PyType_GetBases(PyTypeObject *type);
164164
extern PyObject * _PyType_GetMRO(PyTypeObject *type);
165165
extern PyObject* _PyType_GetSubclasses(PyTypeObject *);
166166
extern int _PyType_HasSubclasses(PyTypeObject *);
167+
PyAPI_FUNC(PyObject *) _PyType_GetModuleByDef2(PyTypeObject *, PyTypeObject *, PyModuleDef *);
167168

168169
// PyType_Ready() must be called if _PyType_IsReady() is false.
169170
// See also the Py_TPFLAGS_READY flag.

Include/internal/pycore_uop_ids.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_metadata.h

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/object.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ static inline Py_ssize_t Py_SIZE(PyObject *ob) {
349349
static inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op)
350350
{
351351
#if defined(Py_GIL_DISABLED)
352-
return (op->ob_ref_local == _Py_IMMORTAL_REFCNT_LOCAL);
352+
return (_Py_atomic_load_uint32_relaxed(&op->ob_ref_local) ==
353+
_Py_IMMORTAL_REFCNT_LOCAL);
353354
#elif SIZEOF_VOID_P > 4
354355
return (_Py_CAST(PY_INT32_T, op->ob_refcnt) < 0);
355356
#else

Lib/ipaddress.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2142,6 +2142,9 @@ def is_loopback(self):
21422142
RFC 2373 2.5.3.
21432143
21442144
"""
2145+
ipv4_mapped = self.ipv4_mapped
2146+
if ipv4_mapped is not None:
2147+
return ipv4_mapped.is_loopback
21452148
return self._ip == 1
21462149

21472150
@property
@@ -2258,7 +2261,7 @@ def is_unspecified(self):
22582261

22592262
@property
22602263
def is_loopback(self):
2261-
return self._ip == 1 and self.network.is_loopback
2264+
return super().is_loopback and self.network.is_loopback
22622265

22632266

22642267
class IPv6Network(_BaseV6, _BaseNetwork):

Lib/test/test_capi/test_mem.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ class C(): pass
153153

154154

155155
# free-threading requires mimalloc (not malloc)
156-
@support.requires_gil_enabled
156+
@support.requires_gil_enabled()
157157
class PyMemMallocDebugTests(PyMemDebugTests):
158158
PYTHONMALLOC = 'malloc_debug'
159159

0 commit comments

Comments
 (0)
0