-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
bpo-46006: Move the interned strings and identifiers to _PyRuntimeState. #30131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
e79afd9
7c6c441
58d9c0b
01f19dc
b60bd33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -233,6 +233,8 @@ static int unicode_is_singleton(PyObject *unicode); | |
#endif | ||
|
||
|
||
#define IDENTIFIERS _Py_SINGLETON(unicode_ids) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you drop the |
||
|
||
static struct _Py_unicode_state* | ||
get_unicode_state(void) | ||
{ | ||
|
@@ -2331,30 +2333,25 @@ PyUnicode_FromString(const char *u) | |
PyObject * | ||
_PyUnicode_FromId(_Py_Identifier *id) | ||
{ | ||
PyInterpreterState *interp = _PyInterpreterState_GET(); | ||
struct _Py_unicode_ids *ids = &interp->unicode.ids; | ||
|
||
Py_ssize_t index = _Py_atomic_size_get(&id->index); | ||
if (index < 0) { | ||
struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_ids; | ||
|
||
PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK); | ||
PyThread_acquire_lock(IDENTIFIERS.lock, WAIT_LOCK); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Drop this, and assert that the GIL is held? |
||
// Check again to detect concurrent access. Another thread can have | ||
// initialized the index while this thread waited for the lock. | ||
index = _Py_atomic_size_get(&id->index); | ||
if (index < 0) { | ||
assert(rt_ids->next_index < PY_SSIZE_T_MAX); | ||
index = rt_ids->next_index; | ||
rt_ids->next_index++; | ||
assert(IDENTIFIERS.next_index < PY_SSIZE_T_MAX); | ||
index = IDENTIFIERS.next_index; | ||
IDENTIFIERS.next_index++; | ||
_Py_atomic_size_set(&id->index, index); | ||
} | ||
PyThread_release_lock(rt_ids->lock); | ||
PyThread_release_lock(IDENTIFIERS.lock); | ||
} | ||
assert(index >= 0); | ||
|
||
PyObject *obj; | ||
if (index < ids->size) { | ||
obj = ids->array[index]; | ||
if (index < IDENTIFIERS.size) { | ||
obj = IDENTIFIERS.array[index]; | ||
if (obj) { | ||
// Return a borrowed reference | ||
return obj; | ||
|
@@ -2368,38 +2365,37 @@ _PyUnicode_FromId(_Py_Identifier *id) | |
} | ||
PyUnicode_InternInPlace(&obj); | ||
|
||
if (index >= ids->size) { | ||
if (index >= IDENTIFIERS.size) { | ||
// Overallocate to reduce the number of realloc | ||
Py_ssize_t new_size = Py_MAX(index * 2, 16); | ||
Py_ssize_t item_size = sizeof(ids->array[0]); | ||
PyObject **new_array = PyMem_Realloc(ids->array, new_size * item_size); | ||
Py_ssize_t item_size = sizeof(IDENTIFIERS.array[0]); | ||
PyObject **new_array = PyMem_Realloc(IDENTIFIERS.array, new_size * item_size); | ||
if (new_array == NULL) { | ||
PyErr_NoMemory(); | ||
return NULL; | ||
} | ||
memset(&new_array[ids->size], 0, (new_size - ids->size) * item_size); | ||
ids->array = new_array; | ||
ids->size = new_size; | ||
memset(&new_array[IDENTIFIERS.size], 0, (new_size - IDENTIFIERS.size) * item_size); | ||
IDENTIFIERS.array = new_array; | ||
IDENTIFIERS.size = new_size; | ||
} | ||
|
||
// The array stores a strong reference | ||
ids->array[index] = obj; | ||
IDENTIFIERS.array[index] = obj; | ||
|
||
// Return a borrowed reference | ||
return obj; | ||
} | ||
|
||
|
||
static void | ||
unicode_clear_identifiers(struct _Py_unicode_state *state) | ||
unicode_clear_identifiers(void) | ||
{ | ||
ericsnowcurrently marked this conversation as resolved.
Show resolved
Hide resolved
|
||
struct _Py_unicode_ids *ids = &state->ids; | ||
for (Py_ssize_t i=0; i < ids->size; i++) { | ||
Py_XDECREF(ids->array[i]); | ||
for (Py_ssize_t i=0; i < IDENTIFIERS.size; i++) { | ||
Py_XDECREF(IDENTIFIERS.array[i]); | ||
} | ||
ids->size = 0; | ||
PyMem_Free(ids->array); | ||
ids->array = NULL; | ||
IDENTIFIERS.size = 0; | ||
PyMem_Free(IDENTIFIERS.array); | ||
IDENTIFIERS.array = NULL; | ||
// Don't reset _PyRuntime next_index: _Py_Identifier.id remains valid | ||
// after Py_Finalize(). | ||
} | ||
|
@@ -16095,7 +16091,7 @@ _PyUnicode_Fini(PyInterpreterState *interp) | |
|
||
_PyUnicode_FiniEncodings(&state->fs_codec); | ||
|
||
unicode_clear_identifiers(state); | ||
unicode_clear_identifiers(); | ||
|
||
for (Py_ssize_t i = 0; i < 256; i++) { | ||
Py_CLEAR(state->latin1[i]); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this lock unnecessary? The GIL is held whenever an identifier is used, isn't it?