Skip to content

Commit 6a3cd5c

Browse files
committed
Merge branch 'main' into specialize-for-compact-ints
2 parents e27d994 + 5f6ab92 commit 6a3cd5c

38 files changed

+1840
-1071
lines changed

Doc/library/dis.rst

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,14 +1094,6 @@ iterations of the loop.
10941094
.. versionadded:: 3.14
10951095

10961096

1097-
.. opcode:: LOAD_CONST_IMMORTAL (consti)
1098-
1099-
Pushes ``co_consts[consti]`` onto the stack.
1100-
Can be used when the constant value is known to be immortal.
1101-
1102-
.. versionadded:: 3.14
1103-
1104-
11051097
.. opcode:: LOAD_NAME (namei)
11061098

11071099
Pushes the value associated with ``co_names[namei]`` onto the stack.

Doc/library/sqlite3.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,15 @@ Module constants
507507
Version number of the runtime SQLite library as a :class:`tuple` of
508508
:class:`integers <int>`.
509509

510+
.. data:: SQLITE_KEYWORDS
511+
512+
A :class:`tuple` containing all sqlite3 keywords.
513+
514+
This constant is only available if Python was compiled with SQLite
515+
3.24.0 or greater.
516+
517+
.. versionadded:: next
518+
510519
.. data:: threadsafety
511520

512521
Integer constant required by the DB-API 2.0, stating the level of thread

Include/internal/pycore_object.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,27 @@ _Py_TryIncref(PyObject *op)
767767
#endif
768768
}
769769

770+
// Enqueue an object to be freed possibly after some delay
771+
#ifdef Py_GIL_DISABLED
772+
PyAPI_FUNC(void) _PyObject_XDecRefDelayed(PyObject *obj);
773+
#else
774+
static inline void _PyObject_XDecRefDelayed(PyObject *obj)
775+
{
776+
Py_XDECREF(obj);
777+
}
778+
#endif
779+
780+
#ifdef Py_GIL_DISABLED
781+
// Same as `Py_XSETREF` but in free-threading, it stores the object atomically
782+
// and queues the old object to be decrefed at a safe point using QSBR.
783+
PyAPI_FUNC(void) _PyObject_XSetRefDelayed(PyObject **p_obj, PyObject *obj);
784+
#else
785+
static inline void _PyObject_XSetRefDelayed(PyObject **p_obj, PyObject *obj)
786+
{
787+
Py_XSETREF(*p_obj, obj);
788+
}
789+
#endif
790+
770791
#ifdef Py_REF_DEBUG
771792
extern void _PyInterpreterState_FinalizeRefTotal(PyInterpreterState *);
772793
extern void _Py_FinalizeRefTotal(_PyRuntimeState *);

Include/internal/pycore_optimizer.h

Lines changed: 78 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ extern "C" {
1010

1111
#include "pycore_typedefs.h" // _PyInterpreterFrame
1212
#include "pycore_uop_ids.h"
13+
#include "pycore_stackref.h"
1314
#include <stdbool.h>
1415

1516

@@ -226,15 +227,58 @@ typedef union _jit_opt_symbol {
226227
} JitOptSymbol;
227228

228229

230+
// This mimics the _PyStackRef API
231+
typedef union {
232+
uintptr_t bits;
233+
} JitOptRef;
234+
235+
#define REF_IS_BORROWED 1
236+
237+
#define JIT_BITS_TO_PTR_MASKED(REF) ((JitOptSymbol *)(((REF).bits) & (~REF_IS_BORROWED)))
238+
239+
static inline JitOptSymbol *
240+
PyJitRef_Unwrap(JitOptRef ref)
241+
{
242+
return JIT_BITS_TO_PTR_MASKED(ref);
243+
}
244+
245+
bool _Py_uop_symbol_is_immortal(JitOptSymbol *sym);
246+
247+
248+
static inline JitOptRef
249+
PyJitRef_Wrap(JitOptSymbol *sym)
250+
{
251+
return (JitOptRef){.bits=(uintptr_t)sym};
252+
}
253+
254+
static inline JitOptRef
255+
PyJitRef_Borrow(JitOptRef ref)
256+
{
257+
return (JitOptRef){ .bits = ref.bits | REF_IS_BORROWED };
258+
}
259+
260+
static const JitOptRef PyJitRef_NULL = {.bits = REF_IS_BORROWED};
261+
262+
static inline bool
263+
PyJitRef_IsNull(JitOptRef ref)
264+
{
265+
return ref.bits == PyJitRef_NULL.bits;
266+
}
267+
268+
static inline int
269+
PyJitRef_IsBorrowed(JitOptRef ref)
270+
{
271+
return (ref.bits & REF_IS_BORROWED) == REF_IS_BORROWED;
272+
}
229273

230274
struct _Py_UOpsAbstractFrame {
231275
// Max stacklen
232276
int stack_len;
233277
int locals_len;
234278

235-
JitOptSymbol **stack_pointer;
236-
JitOptSymbol **stack;
237-
JitOptSymbol **locals;
279+
JitOptRef *stack_pointer;
280+
JitOptRef *stack;
281+
JitOptRef *locals;
238282
};
239283

240284
typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
@@ -257,41 +301,40 @@ typedef struct _JitOptContext {
257301
// Arena for the symbolic types.
258302
ty_arena t_arena;
259303

260-
JitOptSymbol **n_consumed;
261-
JitOptSymbol **limit;
262-
JitOptSymbol *locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
304+
JitOptRef *n_consumed;
305+
JitOptRef *limit;
306+
JitOptRef locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
263307
} JitOptContext;
264308

265-
extern bool _Py_uop_sym_is_null(JitOptSymbol *sym);
266-
extern bool _Py_uop_sym_is_not_null(JitOptSymbol *sym);
267-
extern bool _Py_uop_sym_is_const(JitOptContext *ctx, JitOptSymbol *sym);
268-
extern PyObject *_Py_uop_sym_get_const(JitOptContext *ctx, JitOptSymbol *sym);
269-
extern JitOptSymbol *_Py_uop_sym_new_unknown(JitOptContext *ctx);
270-
extern JitOptSymbol *_Py_uop_sym_new_not_null(JitOptContext *ctx);
271-
extern JitOptSymbol *_Py_uop_sym_new_type(
309+
extern bool _Py_uop_sym_is_null(JitOptRef sym);
310+
extern bool _Py_uop_sym_is_not_null(JitOptRef sym);
311+
extern bool _Py_uop_sym_is_const(JitOptContext *ctx, JitOptRef sym);
312+
extern PyObject *_Py_uop_sym_get_const(JitOptContext *ctx, JitOptRef sym);
313+
extern JitOptRef _Py_uop_sym_new_unknown(JitOptContext *ctx);
314+
extern JitOptRef _Py_uop_sym_new_not_null(JitOptContext *ctx);
315+
extern JitOptRef _Py_uop_sym_new_type(
272316
JitOptContext *ctx, PyTypeObject *typ);
273-
extern JitOptSymbol *_Py_uop_sym_new_const(JitOptContext *ctx, PyObject *const_val);
274-
extern JitOptSymbol *_Py_uop_sym_new_null(JitOptContext *ctx);
275-
extern bool _Py_uop_sym_has_type(JitOptSymbol *sym);
276-
extern bool _Py_uop_sym_matches_type(JitOptSymbol *sym, PyTypeObject *typ);
277-
extern bool _Py_uop_sym_matches_type_version(JitOptSymbol *sym, unsigned int version);
278-
extern void _Py_uop_sym_set_null(JitOptContext *ctx, JitOptSymbol *sym);
279-
extern void _Py_uop_sym_set_non_null(JitOptContext *ctx, JitOptSymbol *sym);
280-
extern void _Py_uop_sym_set_type(JitOptContext *ctx, JitOptSymbol *sym, PyTypeObject *typ);
281-
extern bool _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptSymbol *sym, unsigned int version);
282-
extern void _Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val);
283-
extern bool _Py_uop_sym_is_bottom(JitOptSymbol *sym);
284-
extern int _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptSymbol *sym);
285-
extern PyTypeObject *_Py_uop_sym_get_type(JitOptSymbol *sym);
286-
extern bool _Py_uop_sym_is_immortal(JitOptSymbol *sym);
287-
extern JitOptSymbol *_Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args);
288-
extern JitOptSymbol *_Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptSymbol *sym, int item);
289-
extern int _Py_uop_sym_tuple_length(JitOptSymbol *sym);
290-
extern JitOptSymbol *_Py_uop_sym_new_truthiness(JitOptContext *ctx, JitOptSymbol *value, bool truthy);
291-
extern bool _Py_uop_sym_is_compact_int(JitOptSymbol *sym);
292-
extern JitOptSymbol *_Py_uop_sym_new_compact_int(JitOptContext *ctx);
293-
extern void _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptSymbol *value);
294317

318+
extern JitOptRef _Py_uop_sym_new_const(JitOptContext *ctx, PyObject *const_val);
319+
extern JitOptRef _Py_uop_sym_new_null(JitOptContext *ctx);
320+
extern bool _Py_uop_sym_has_type(JitOptRef sym);
321+
extern bool _Py_uop_sym_matches_type(JitOptRef sym, PyTypeObject *typ);
322+
extern bool _Py_uop_sym_matches_type_version(JitOptRef sym, unsigned int version);
323+
extern void _Py_uop_sym_set_null(JitOptContext *ctx, JitOptRef sym);
324+
extern void _Py_uop_sym_set_non_null(JitOptContext *ctx, JitOptRef sym);
325+
extern void _Py_uop_sym_set_type(JitOptContext *ctx, JitOptRef sym, PyTypeObject *typ);
326+
extern bool _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptRef sym, unsigned int version);
327+
extern void _Py_uop_sym_set_const(JitOptContext *ctx, JitOptRef sym, PyObject *const_val);
328+
extern bool _Py_uop_sym_is_bottom(JitOptRef sym);
329+
extern int _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptRef sym);
330+
extern PyTypeObject *_Py_uop_sym_get_type(JitOptRef sym);
331+
extern JitOptRef _Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptRef *args);
332+
extern JitOptRef _Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptRef sym, int item);
333+
extern int _Py_uop_sym_tuple_length(JitOptRef sym);
334+
extern JitOptRef _Py_uop_sym_new_truthiness(JitOptContext *ctx, JitOptRef value, bool truthy);
335+
extern bool _Py_uop_sym_is_compact_int(JitOptRef sym);
336+
extern JitOptRef _Py_uop_sym_new_compact_int(JitOptContext *ctx);
337+
extern void _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef sym);
295338

296339
extern void _Py_uop_abstractcontext_init(JitOptContext *ctx);
297340
extern void _Py_uop_abstractcontext_fini(JitOptContext *ctx);
@@ -300,7 +343,7 @@ extern _Py_UOpsAbstractFrame *_Py_uop_frame_new(
300343
JitOptContext *ctx,
301344
PyCodeObject *co,
302345
int curr_stackentries,
303-
JitOptSymbol **args,
346+
JitOptRef *args,
304347
int arg_len);
305348
extern int _Py_uop_frame_pop(JitOptContext *ctx);
306349

Include/internal/pycore_pymem.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,6 @@ extern int _PyMem_DebugEnabled(void);
9090
// Enqueue a pointer to be freed possibly after some delay.
9191
extern void _PyMem_FreeDelayed(void *ptr);
9292

93-
// Enqueue an object to be freed possibly after some delay
94-
#ifdef Py_GIL_DISABLED
95-
PyAPI_FUNC(void) _PyObject_XDecRefDelayed(PyObject *obj);
96-
#else
97-
static inline void _PyObject_XDecRefDelayed(PyObject *obj)
98-
{
99-
Py_XDECREF(obj);
100-
}
101-
#endif
102-
10393
// Periodically process delayed free requests.
10494
extern void _PyMem_ProcessDelayed(PyThreadState *tstate);
10595

0 commit comments

Comments
 (0)