gh-128137: Update PyASCIIObject to handle interned field with the atomic operation (gh-128196)

This commit is contained in:
Donghee Na 2025-01-05 18:17:06 +09:00 committed by GitHub
parent b60044b838
commit ae23a012e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 18 additions and 10 deletions

View file

@ -109,7 +109,7 @@ typedef struct {
3: Interned, Immortal, and Static 3: Interned, Immortal, and Static
This categorization allows the runtime to determine the right This categorization allows the runtime to determine the right
cleanup mechanism at runtime shutdown. */ cleanup mechanism at runtime shutdown. */
unsigned int interned:2; uint16_t interned;
/* Character size: /* Character size:
- PyUnicode_1BYTE_KIND (1): - PyUnicode_1BYTE_KIND (1):
@ -132,21 +132,23 @@ typedef struct {
* all characters are in the range U+0000-U+10FFFF * all characters are in the range U+0000-U+10FFFF
* at least one character is in the range U+10000-U+10FFFF * at least one character is in the range U+10000-U+10FFFF
*/ */
unsigned int kind:3; unsigned short kind:3;
/* Compact is with respect to the allocation scheme. Compact unicode /* Compact is with respect to the allocation scheme. Compact unicode
objects only require one memory block while non-compact objects use objects only require one memory block while non-compact objects use
one block for the PyUnicodeObject struct and another for its data one block for the PyUnicodeObject struct and another for its data
buffer. */ buffer. */
unsigned int compact:1; unsigned short compact:1;
/* The string only contains characters in the range U+0000-U+007F (ASCII) /* The string only contains characters in the range U+0000-U+007F (ASCII)
and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is
set, use the PyASCIIObject structure. */ set, use the PyASCIIObject structure. */
unsigned int ascii:1; unsigned short ascii:1;
/* The object is statically allocated. */ /* The object is statically allocated. */
unsigned int statically_allocated:1; unsigned short statically_allocated:1;
/* Padding to ensure that PyUnicode_DATA() is always aligned to /* Padding to ensure that PyUnicode_DATA() is always aligned to
4 bytes (see issue #19537 on m68k). */ 4 bytes (see issue #19537 on m68k) and we use unsigned short to avoid
unsigned int :24; the extra four bytes on 32-bit Windows. This is restricted features
for specific compilers including GCC, MSVC, Clang and IBM's XL compiler. */
unsigned short :10;
} state; } state;
} PyASCIIObject; } PyASCIIObject;
@ -195,7 +197,11 @@ typedef struct {
/* Use only if you know it's a string */ /* Use only if you know it's a string */
static inline unsigned int PyUnicode_CHECK_INTERNED(PyObject *op) { static inline unsigned int PyUnicode_CHECK_INTERNED(PyObject *op) {
#ifdef Py_GIL_DISABLED
return _Py_atomic_load_uint16_relaxed(&_PyASCIIObject_CAST(op)->state.interned);
#else
return _PyASCIIObject_CAST(op)->state.interned; return _PyASCIIObject_CAST(op)->state.interned;
#endif
} }
#define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op)) #define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op))

View file

@ -0,0 +1,2 @@
Update :c:type:`PyASCIIObject` layout to handle interned field with the
atomic operation. Patch by Donghee Na.

View file

@ -15729,7 +15729,7 @@ immortalize_interned(PyObject *s)
_Py_DecRefTotal(_PyThreadState_GET()); _Py_DecRefTotal(_PyThreadState_GET());
} }
#endif #endif
_PyUnicode_STATE(s).interned = SSTATE_INTERNED_IMMORTAL; FT_ATOMIC_STORE_UINT16_RELAXED(_PyUnicode_STATE(s).interned, SSTATE_INTERNED_IMMORTAL);
_Py_SetImmortal(s); _Py_SetImmortal(s);
} }
@ -15848,7 +15848,7 @@ intern_common(PyInterpreterState *interp, PyObject *s /* stolen */,
_Py_DecRefTotal(_PyThreadState_GET()); _Py_DecRefTotal(_PyThreadState_GET());
#endif #endif
} }
_PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL; FT_ATOMIC_STORE_UINT16_RELAXED(_PyUnicode_STATE(s).interned, SSTATE_INTERNED_MORTAL);
/* INTERNED_MORTAL -> INTERNED_IMMORTAL (if needed) */ /* INTERNED_MORTAL -> INTERNED_IMMORTAL (if needed) */
@ -15984,7 +15984,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp)
Py_UNREACHABLE(); Py_UNREACHABLE();
} }
if (!shared) { if (!shared) {
_PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; FT_ATOMIC_STORE_UINT16_RELAXED(_PyUnicode_STATE(s).interned, SSTATE_NOT_INTERNED);
} }
} }
#ifdef INTERNED_STATS #ifdef INTERNED_STATS