From ffbf24bf0cc297d080d6d68bc809a9c156c49123 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 22 Feb 2011 20:15:44 +0000 Subject: Issue #8914: fix various warnings from the Clang static analyzer v254. --- Objects/floatobject.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Objects/floatobject.c') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 09c0e961ba..6d1745e2c3 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -197,7 +197,6 @@ PyFloat_FromString(PyObject *v) Py_DECREF(s_buffer); return NULL; } - last = s + len; } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, @@ -2246,7 +2245,7 @@ _PyFloat_Pack8(double x, unsigned char *p, int le) /* Eighth byte */ *p = flo & 0xFF; - p += incr; + /* p += incr; */ /* Done */ return 0; -- cgit v1.2.1 From a4350798d054973b1c8a6cbfc54edd8ddbe416b6 Mon Sep 17 00:00:00 2001 From: Jesus Cea Date: Mon, 14 Mar 2011 17:36:54 +0100 Subject: Issue #11495: OSF support is eliminated. It was deprecated in Python 3.2 --- Objects/floatobject.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'Objects/floatobject.c') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 6d1745e2c3..33926148c0 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -15,11 +15,6 @@ #define MIN(x, y) ((x) < (y) ? (x) : (y)) -#ifdef _OSF_SOURCE -/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ -extern int finite(double); -#endif - /* Special free list Since some Python programs can spend much of their time allocating -- cgit v1.2.1 From 174958263e0e4854bb560dd8609a76e797cc66f7 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 10 Aug 2011 20:28:54 -0500 Subject: Replace Py_NotImplemented returns with the macro form Py_RETURN_NOTIMPLEMENTED. The macro was introduced in #12724. --- Objects/floatobject.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Objects/floatobject.c') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 33926148c0..a031d1b63b 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -517,8 +517,7 @@ float_richcompare(PyObject *v, PyObject *w, int op) return PyBool_FromLong(r); Unimplemented: - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + Py_RETURN_NOTIMPLEMENTED; } static Py_hash_t -- cgit v1.2.1 From d1d013c01c268d869597b35cbcd8b5d7c5baf2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Wed, 28 Sep 2011 07:41:54 +0200 Subject: Implement PEP 393. --- Objects/floatobject.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'Objects/floatobject.c') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index a031d1b63b..1c8a6a32a3 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -174,20 +174,10 @@ PyFloat_FromString(PyObject *v) PyObject *result = NULL; if (PyUnicode_Check(v)) { - Py_ssize_t i, buflen = PyUnicode_GET_SIZE(v); - Py_UNICODE *bufptr; - s_buffer = PyUnicode_TransformDecimalToASCII( - PyUnicode_AS_UNICODE(v), buflen); + s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); if (s_buffer == NULL) return NULL; - /* Replace non-ASCII whitespace with ' ' */ - bufptr = PyUnicode_AS_UNICODE(s_buffer); - for (i = 0; i < buflen; i++) { - Py_UNICODE ch = bufptr[i]; - if (ch > 127 && Py_UNICODE_ISSPACE(ch)) - bufptr[i] = ' '; - } - s = _PyUnicode_AsStringAndSize(s_buffer, &len); + s = PyUnicode_AsUTF8AndSize(s_buffer, &len); if (s == NULL) { Py_DECREF(s_buffer); return NULL; @@ -1741,9 +1731,8 @@ float__format__(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) return NULL; - return _PyFloat_FormatAdvanced(self, - PyUnicode_AS_UNICODE(format_spec), - PyUnicode_GET_SIZE(format_spec)); + return _PyFloat_FormatAdvanced(self, format_spec, 0, + PyUnicode_GET_LENGTH(format_spec)); } PyDoc_STRVAR(float__format__doc, -- cgit v1.2.1 From da328a42858356139f9e6de860b802408ed76f5d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Oct 2011 02:13:11 +0200 Subject: Issue #13088: Add shared Py_hexdigits constant to format a number into base 16 --- Objects/floatobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects/floatobject.c') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 1c8a6a32a3..4e0fa7da0a 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1058,7 +1058,7 @@ static char char_from_hex(int x) { assert(0 <= x && x < 16); - return "0123456789abcdef"[x]; + return Py_hexdigits[x]; } static int -- cgit v1.2.1 From 1d6f085aba426341ea2278b83f79df086c6e9221 Mon Sep 17 00:00:00 2001 From: Kristj?n Valur J?nsson Date: Fri, 30 Mar 2012 09:18:15 +0000 Subject: Issue #14435: Remove special block allocation code from floatobject.c PyFloatObjects are now allocated using PyObject_MALLOC like all other internal types, but maintain a limited freelist of objects at hand for performance. This will result in more consistent memory usage by Python. --- Objects/floatobject.c | 158 +++++++++----------------------------------------- 1 file changed, 27 insertions(+), 131 deletions(-) (limited to 'Objects/floatobject.c') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index a738249790..07d31b296a 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -16,53 +16,16 @@ /* Special free list - - Since some Python programs can spend much of their time allocating - and deallocating floats, these operations should be very fast. - Therefore we use a dedicated allocation scheme with a much lower - overhead (in space and time) than straight malloc(): a simple - dedicated free list, filled when necessary with memory from malloc(). - - block_list is a singly-linked list of all PyFloatBlocks ever allocated, - linked via their next members. PyFloatBlocks are never returned to the - system before shutdown (PyFloat_Fini). - free_list is a singly-linked list of available PyFloatObjects, linked via abuse of their ob_type members. */ -#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */ -#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */ -#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject)) - -struct _floatblock { - struct _floatblock *next; - PyFloatObject objects[N_FLOATOBJECTS]; -}; - -typedef struct _floatblock PyFloatBlock; - -static PyFloatBlock *block_list = NULL; +#ifndef PyFloat_MAXFREELIST +#define PyFloat_MAXFREELIST 100 +#endif +static int numfree = 0; static PyFloatObject *free_list = NULL; -static PyFloatObject * -fill_free_list(void) -{ - PyFloatObject *p, *q; - /* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */ - p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock)); - if (p == NULL) - return (PyFloatObject *) PyErr_NoMemory(); - ((PyFloatBlock *)p)->next = block_list; - block_list = (PyFloatBlock *)p; - p = &((PyFloatBlock *)p)->objects[0]; - q = p + N_FLOATOBJECTS; - while (--q > p) - Py_TYPE(q) = (struct _typeobject *)(q-1); - Py_TYPE(q) = NULL; - return p + N_FLOATOBJECTS - 1; -} - double PyFloat_GetMax(void) { @@ -151,14 +114,16 @@ PyFloat_GetInfo(void) PyObject * PyFloat_FromDouble(double fval) { - register PyFloatObject *op; - if (free_list == NULL) { - if ((free_list = fill_free_list()) == NULL) - return NULL; + register PyFloatObject *op = free_list; + if (op != NULL) { + free_list = (PyFloatObject *) Py_TYPE(op); + numfree--; + } else { + op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject)); + if (!op) + return PyErr_NoMemory(); } /* Inline PyObject_New */ - op = free_list; - free_list = (PyFloatObject *)Py_TYPE(op); PyObject_INIT(op, &PyFloat_Type); op->ob_fval = fval; return (PyObject *) op; @@ -217,6 +182,11 @@ static void float_dealloc(PyFloatObject *op) { if (PyFloat_CheckExact(op)) { + if (numfree >= PyFloat_MAXFREELIST) { + PyObject_FREE(op); + return; + } + numfree++; Py_TYPE(op) = (struct _typeobject *)free_list; free_list = op; } @@ -1932,96 +1902,22 @@ _PyFloat_Init(void) int PyFloat_ClearFreeList(void) { - PyFloatObject *p; - PyFloatBlock *list, *next; - int i; - int u; /* remaining unfreed floats per block */ - int freelist_size = 0; - - list = block_list; - block_list = NULL; - free_list = NULL; - while (list != NULL) { - u = 0; - for (i = 0, p = &list->objects[0]; - i < N_FLOATOBJECTS; - i++, p++) { - if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0) - u++; - } - next = list->next; - if (u) { - list->next = block_list; - block_list = list; - for (i = 0, p = &list->objects[0]; - i < N_FLOATOBJECTS; - i++, p++) { - if (!PyFloat_CheckExact(p) || - Py_REFCNT(p) == 0) { - Py_TYPE(p) = (struct _typeobject *) - free_list; - free_list = p; - } - } - } - else { - PyMem_FREE(list); - } - freelist_size += u; - list = next; + PyFloatObject *f = free_list, *next; + int i = numfree; + while (f) { + next = (PyFloatObject*) Py_TYPE(f); + PyObject_FREE(f); + f = next; } - return freelist_size; + free_list = NULL; + numfree = 0; + return i; } void PyFloat_Fini(void) { - PyFloatObject *p; - PyFloatBlock *list; - int i; - int u; /* total unfreed floats per block */ - - u = PyFloat_ClearFreeList(); - - if (!Py_VerboseFlag) - return; - fprintf(stderr, "# cleanup floats"); - if (!u) { - fprintf(stderr, "\n"); - } - else { - fprintf(stderr, - ": %d unfreed float%s\n", - u, u == 1 ? "" : "s"); - } - if (Py_VerboseFlag > 1) { - list = block_list; - while (list != NULL) { - for (i = 0, p = &list->objects[0]; - i < N_FLOATOBJECTS; - i++, p++) { - if (PyFloat_CheckExact(p) && - Py_REFCNT(p) != 0) { - char *buf = PyOS_double_to_string( - PyFloat_AS_DOUBLE(p), 'r', - 0, 0, NULL); - if (buf) { - /* XXX(twouters) cast - refcount to long - until %zd is - universally - available - */ - fprintf(stderr, - "# \n", - p, (long)Py_REFCNT(p), buf); - PyMem_Free(buf); - } - } - } - list = list->next; - } - } + (void)PyFloat_ClearFreeList(); } /*---------------------------------------------------------------------------- -- cgit v1.2.1