Skip to content

Commit d63bf96

Browse files
Subbarao Garlapatimeta-codesync[bot]
authored andcommitted
Add Lazy Imports to 3.14t
Summary: Add Lazy Imports to the free-threaded build of Meta Python 3.14. Lazy Imports was added to the gil build of Meta Python 3.14 in D83595369. This Diff is the result of squashing this stack: D85054995. The stack must be landed in one commit to avoid introducing any dangerous behavior in 3.14t. Reviewed By: DinoV Differential Revision: D85977460 fbshipit-source-id: f11501c8996c55cb83952016916f88b5f9d05636
1 parent ec9d8c1 commit d63bf96

File tree

17 files changed

+607
-133
lines changed

17 files changed

+607
-133
lines changed

Include/cpython/pyatomic.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,12 @@ _Py_atomic_load_uint32_acquire(const uint32_t *obj);
544544
static inline Py_ssize_t
545545
_Py_atomic_load_ssize_acquire(const Py_ssize_t *obj);
546546

547+
static inline void
548+
_Py_atomic_store_uchar_release(unsigned char *obj, unsigned char value);
549+
550+
static inline unsigned char
551+
_Py_atomic_load_uchar_acquire(const unsigned char *obj);
552+
547553

548554

549555

Include/cpython/pyatomic_gcc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,14 @@ static inline Py_ssize_t
600600
_Py_atomic_load_ssize_acquire(const Py_ssize_t *obj)
601601
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
602602

603+
static inline unsigned char
604+
_Py_atomic_load_uchar_acquire(const unsigned char *obj)
605+
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
606+
607+
static inline void
608+
_Py_atomic_store_uchar_release(unsigned char *obj, unsigned char value)
609+
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
610+
603611
// --- _Py_atomic_fence ------------------------------------------------------
604612

605613
static inline void

Include/cpython/pyatomic_std.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,22 @@ _Py_atomic_load_ssize_acquire(const Py_ssize_t *obj)
10871087
memory_order_acquire);
10881088
}
10891089

1090+
static inline void
1091+
_Py_atomic_store_uchar_release(unsigned char *obj, unsigned char value)
1092+
{
1093+
_Py_USING_STD;
1094+
atomic_store_explicit((_Atomic(unsigned char)*)obj, value,
1095+
memory_order_release);
1096+
}
1097+
1098+
static inline unsigned char
1099+
_Py_atomic_load_uchar_acquire(const unsigned char *obj)
1100+
{
1101+
_Py_USING_STD;
1102+
return atomic_load_explicit((const _Atomic(unsigned char)*)obj,
1103+
memory_order_acquire);
1104+
}
1105+
10901106

10911107
// --- _Py_atomic_fence ------------------------------------------------------
10921108

Include/internal/pycore_dict.h

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,24 @@ PyAPI_FUNC(void) _PyDict_EnsureSharedOnRead(PyDictObject *mp);
174174
typedef enum {
175175
DICT_KEYS_GENERAL = 0,
176176
DICT_KEYS_UNICODE = 1,
177-
DICT_KEYS_SPLIT = 2
177+
DICT_KEYS_SPLIT = 2,
178+
DICT_KEYS_LAZY_IMPORTS = 0x80,
178179
} DictKeysKind;
179180

181+
#define DICT_KEYS_KIND_MASK 0x03
182+
#define DICT_KEYS_LAZY_IMPORTS_MASK 0x80
183+
184+
#ifdef ENABLE_LAZY_IMPORTS
185+
#define LOAD_SHARED_UCHAR(obj) _Py_atomic_load_uchar_acquire(&obj)
186+
#define STORE_SHARED_UCHAR(obj, value) _Py_atomic_store_uchar_release(&obj, value)
187+
#define DK_KIND(dk) (LOAD_SHARED_UCHAR(dk->dk_kind) & DICT_KEYS_KIND_MASK)
188+
#define DK_LAZY_IMPORTS(dk) (LOAD_SHARED_UCHAR(dk->dk_kind) & DICT_KEYS_LAZY_IMPORTS)
189+
#else
190+
#define LOAD_SHARED_UCHAR(obj) obj
191+
#define STORE_SHARED_UCHAR(obj, value) obj = value
192+
#define DK_KIND(dk) (dk->dk_kind)
193+
#endif
194+
180195
/* See dictobject.c for actual layout of DictKeysObject */
181196
struct _dictkeysobject {
182197
Py_ssize_t dk_refcnt;
@@ -187,15 +202,8 @@ struct _dictkeysobject {
187202
/* Size of the hash table (dk_indices) by bytes. */
188203
uint8_t dk_log2_index_bytes;
189204

190-
/* Kind of keys */
191-
#ifdef ENABLE_LAZY_IMPORTS
192-
uint8_t dk_kind: 7;
193-
194-
/* Contains lazy imports. Assume there are lazy import objects unless otherwise specified. */
195-
uint8_t dk_lazy_imports : 1;
196-
#else
205+
/* Kind of keys (use `DICT_KEYS_KIND_MASK` to get kind, `DICT_KEYS_LAZY_IMPORTS` flag for lazy imports) */
197206
uint8_t dk_kind;
198-
#endif
199207

200208
#ifdef Py_GIL_DISABLED
201209
/* Lock used to protect shared keys */
@@ -263,15 +271,15 @@ static inline void* _DK_ENTRIES(PyDictKeysObject *dk) {
263271
}
264272

265273
static inline PyDictKeyEntry* DK_ENTRIES(PyDictKeysObject *dk) {
266-
assert(dk->dk_kind == DICT_KEYS_GENERAL);
274+
assert(DK_KIND(dk) == DICT_KEYS_GENERAL);
267275
return (PyDictKeyEntry*)_DK_ENTRIES(dk);
268276
}
269277
static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) {
270-
assert(dk->dk_kind != DICT_KEYS_GENERAL);
278+
assert(DK_KIND(dk) != DICT_KEYS_GENERAL);
271279
return (PyDictUnicodeEntry*)_DK_ENTRIES(dk);
272280
}
273281

274-
#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL)
282+
#define DK_IS_UNICODE(dk) (DK_KIND(dk) != DICT_KEYS_GENERAL)
275283

276284
#define DICT_VERSION_INCREMENT (1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS))
277285
#define DICT_WATCHER_MASK ((1 << DICT_MAX_WATCHERS) - 1)

Include/internal/pycore_interp_structs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ struct _is {
980980
PyObject *excluding_modules;
981981
PyObject *eager_imports;
982982
PyObject *lazy_modules;
983+
PyMutex lazy_imports_mutex;
983984
#endif
984985
};
985986

Lib/test/test_lazy_imports.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010

1111
class LazyImportsTest(unittest.TestCase):
1212
def test_lazy_imports(self):
13-
# TODO-META: Remove when Lazy Imports is added to 3.14t
14-
if not sys._is_gil_enabled():
15-
return
1613
original_lazy_modules = sys.lazy_modules.copy()
1714
original_modules = sys.modules.copy()
1815
try:

0 commit comments

Comments
 (0)