Index: Objects/stringobject.c =================================================================== --- Objects/stringobject.c (revision 67424) +++ Objects/stringobject.c (working copy) @@ -4,6 +4,7 @@ #include "Python.h" #include +#include #ifdef COUNT_ALLOCS int null_strings, one_strings; @@ -22,6 +23,14 @@ */ static PyObject *interned; +/* PyStringObject_SIZE gives the basic size of a string; any memory allocation + for a string of length n should request PyStringObject_SIZE + n bytes. + + Using PyStringObject_SIZE instead of sizeof(PyStringObject) saves + 3 bytes per string allocation on a typical system. +*/ +#define PyStringObject_SIZE (offsetof(PyStringObject, ob_sval) + 1) + /* For both PyString_FromString() and PyString_FromStringAndSize(), the parameter `size' denotes number of characters to allocate, not counting any @@ -74,13 +83,13 @@ return (PyObject *)op; } - if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) { + if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) { PyErr_SetString(PyExc_OverflowError, "string is too large"); return NULL; } /* Inline PyObject_NewVar */ - op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size); + op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); PyObject_INIT_VAR(op, &PyString_Type, size); @@ -114,7 +123,7 @@ assert(str != NULL); size = strlen(str); - if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) { + if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) { PyErr_SetString(PyExc_OverflowError, "string is too long for a Python string"); return NULL; @@ -135,7 +144,7 @@ } /* Inline PyObject_NewVar */ - op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size); + op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); PyObject_INIT_VAR(op, &PyString_Type, size); @@ -992,14 +1001,14 @@ "strings are too large to concat"); return NULL; } - + /* Inline PyObject_NewVar */ - if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) { + if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) { PyErr_SetString(PyExc_OverflowError, "strings are too large to concat"); return NULL; } - op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size); + op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); PyObject_INIT_VAR(op, &PyString_Type, size); @@ -1036,13 +1045,12 @@ return (PyObject *)a; } nbytes = (size_t)size; - if (nbytes + sizeof(PyStringObject) <= nbytes) { + if (nbytes + PyStringObject_SIZE <= nbytes) { PyErr_SetString(PyExc_OverflowError, "repeated string is too long"); return NULL; } - op = (PyStringObject *) - PyObject_MALLOC(sizeof(PyStringObject) + nbytes); + op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + nbytes); if (op == NULL) return PyErr_NoMemory(); PyObject_INIT_VAR(op, &PyString_Type, size); @@ -3940,7 +3948,7 @@ string_sizeof(PyStringObject *v) { Py_ssize_t res; - res = sizeof(PyStringObject) + v->ob_size * v->ob_type->tp_itemsize; + res = PyStringObject_SIZE + v->ob_size * v->ob_type->tp_itemsize; return PyInt_FromSsize_t(res); } @@ -4179,7 +4187,7 @@ PyTypeObject PyString_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "str", - sizeof(PyStringObject), + PyStringObject_SIZE, sizeof(char), string_dealloc, /* tp_dealloc */ (printfunc)string_print, /* tp_print */ @@ -4275,7 +4283,7 @@ _Py_DEC_REFTOTAL; _Py_ForgetReference(v); *pv = (PyObject *) - PyObject_REALLOC((char *)v, sizeof(PyStringObject) + newsize); + PyObject_REALLOC((char *)v, PyStringObject_SIZE + newsize); if (*pv == NULL) { PyObject_Del(v); PyErr_NoMemory(); Index: Lib/test/test_sys.py =================================================================== --- Lib/test/test_sys.py (revision 67424) +++ Lib/test/test_sys.py (working copy) @@ -631,8 +631,8 @@ # slice check(slice(1), size(h + '3P')) # str - check('', size(vh + 'lic')) - check('abc', size(vh + 'lic') + 3*self.c) + check('', struct.calcsize(vh + 'li') + 1) + check('abc', struct.calcsize(vh + 'li') + 1 + 3*self.c) # super check(super(int), size(h + '3P')) # tuple