diff options
author | Victor Stinner <vstinner@python.org> | 2020-06-23 13:54:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-23 13:54:35 (GMT) |
commit | c41eed1a874e2f22bde45c3c89418414b7a37f46 (patch) | |
tree | e90ff0bf1c5349169f3f04c914695b3c4b476f37 /Objects/bytesobject.c | |
parent | 32f2eda85957365d208f499b730d30b7eb419741 (diff) | |
download | cpython-c41eed1a874e2f22bde45c3c89418414b7a37f46.zip cpython-c41eed1a874e2f22bde45c3c89418414b7a37f46.tar.gz cpython-c41eed1a874e2f22bde45c3c89418414b7a37f46.tar.bz2 |
bpo-40521: Make bytes singletons per interpreter (GH-21074)
Each interpreter now has its own empty bytes string and single byte
character singletons.
Replace STRINGLIB_EMPTY macro with STRINGLIB_GET_EMPTY() macro.
Diffstat (limited to 'Objects/bytesobject.c')
-rw-r--r-- | Objects/bytesobject.c | 82 |
1 files changed, 55 insertions, 27 deletions
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index d397214..ce006e1 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -18,9 +18,6 @@ class bytes "PyBytesObject *" "&PyBytes_Type" #include "clinic/bytesobject.c.h" -static PyBytesObject *characters[UCHAR_MAX + 1]; -static PyBytesObject *nullstring; - _Py_IDENTIFIER(__bytes__); /* PyBytesObject_SIZE gives the basic size of a string; any memory allocation @@ -35,6 +32,15 @@ _Py_IDENTIFIER(__bytes__); Py_LOCAL_INLINE(Py_ssize_t) _PyBytesWriter_GetSize(_PyBytesWriter *writer, char *str); + +static struct _Py_bytes_state* +get_bytes_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return &interp->bytes; +} + + /* For PyBytes_FromString(), the parameter `str' points to a null-terminated string containing exactly `size' bytes. @@ -63,9 +69,13 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc) PyBytesObject *op; assert(size >= 0); - if (size == 0 && (op = nullstring) != NULL) { - Py_INCREF(op); - return (PyObject *)op; + if (size == 0) { + struct _Py_bytes_state *state = get_bytes_state(); + op = state->empty_string; + if (op != NULL) { + Py_INCREF(op); + return (PyObject *)op; + } } if ((size_t)size > (size_t)PY_SSIZE_T_MAX - PyBytesObject_SIZE) { @@ -88,8 +98,9 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc) op->ob_sval[size] = '\0'; /* empty byte string singleton */ if (size == 0) { - nullstring = op; + struct _Py_bytes_state *state = get_bytes_state(); Py_INCREF(op); + state->empty_string = op; } return (PyObject *) op; } @@ -103,11 +114,13 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) "Negative size passed to PyBytes_FromStringAndSize"); return NULL; } - if (size == 1 && str != NULL && - (op = characters[*str & UCHAR_MAX]) != NULL) - { - Py_INCREF(op); - return (PyObject *)op; + if (size == 1 && str != NULL) { + struct _Py_bytes_state *state = get_bytes_state(); + op = state->characters[*str & UCHAR_MAX]; + if (op != NULL) { + Py_INCREF(op); + return (PyObject *)op; + } } op = (PyBytesObject *)_PyBytes_FromSize(size, 0); @@ -119,8 +132,9 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) memcpy(op->ob_sval, str, size); /* share short strings */ if (size == 1) { - characters[*str & UCHAR_MAX] = op; + struct _Py_bytes_state *state = get_bytes_state(); Py_INCREF(op); + state->characters[*str & UCHAR_MAX] = op; } return (PyObject *) op; } @@ -138,13 +152,21 @@ PyBytes_FromString(const char *str) "byte string is too long"); return NULL; } - if (size == 0 && (op = nullstring) != NULL) { - Py_INCREF(op); - return (PyObject *)op; + + struct _Py_bytes_state *state = get_bytes_state(); + if (size == 0) { + op = state->empty_string; + if (op != NULL) { + Py_INCREF(op); + return (PyObject *)op; + } } - if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) { - Py_INCREF(op); - return (PyObject *)op; + else if (size == 1) { + op = state->characters[*str & UCHAR_MAX]; + if (op != NULL) { + Py_INCREF(op); + return (PyObject *)op; + } } /* Inline PyObject_NewVar */ @@ -157,11 +179,12 @@ PyBytes_FromString(const char *str) memcpy(op->ob_sval, str, size+1); /* share short strings */ if (size == 0) { - nullstring = op; Py_INCREF(op); - } else if (size == 1) { - characters[*str & UCHAR_MAX] = op; + state->empty_string = op; + } + else if (size == 1) { Py_INCREF(op); + state->characters[*str & UCHAR_MAX] = op; } return (PyObject *) op; } @@ -1249,6 +1272,8 @@ PyBytes_AsStringAndSize(PyObject *obj, /* -------------------------------------------------------------------- */ /* Methods */ +#define STRINGLIB_GET_EMPTY() get_bytes_state()->empty_string + #include "stringlib/stringdefs.h" #include "stringlib/fastsearch.h" @@ -1261,6 +1286,8 @@ PyBytes_AsStringAndSize(PyObject *obj, #include "stringlib/transmogrify.h" +#undef STRINGLIB_GET_EMPTY + PyObject * PyBytes_Repr(PyObject *obj, int smartquotes) { @@ -3058,12 +3085,13 @@ error: } void -_PyBytes_Fini(void) +_PyBytes_Fini(PyThreadState *tstate) { - int i; - for (i = 0; i < UCHAR_MAX + 1; i++) - Py_CLEAR(characters[i]); - Py_CLEAR(nullstring); + struct _Py_bytes_state* state = &tstate->interp->bytes; + for (int i = 0; i < UCHAR_MAX + 1; i++) { + Py_CLEAR(state->characters[i]); + } + Py_CLEAR(state->empty_string); } /*********************** Bytes Iterator ****************************/ |