[Python-checkins] python/dist/src/Include pymem.h,2.12,2.13 pyport.h,2.46,2.47

tim_one@sourceforge.net tim_one@sourceforge.net
Fri, 12 Apr 2002 00:22:58 -0700


Update of /cvsroot/python/python/dist/src/Include
In directory usw-pr-cvs1:/tmp/cvs-serv31971/python/Include

Modified Files:
	pymem.h pyport.h 
Log Message:
First stab at rationalizing the PyMem_ API.  Mixing PyObject_xyz with
PyMem_{Del, DEL} doesn't work yet (compilation problems).

pyport.h:  _PyMem_EXTRA is gone.

pmem.h:  Repaired comments.  PyMem_{Malloc, MALLOC} and
PyMem_{Realloc, REALLOC} now make the same x-platform guarantees when
asking for 0 bytes, and when passing a NULL pointer to the latter.

object.c:  PyMem_{Malloc, Realloc} just call their macro versions
now, since the latter take care of the x-platform 0 and NULL stuff
by themselves now.

pypcre.c, grow_stack():  So sue me.  On two lines, this called
PyMem_RESIZE to grow a "const" area.  It's not legit to realloc a
const area, so the compiler warned given the new expansion of
PyMem_RESIZE.  It would have gotten the same warning before if it
had used PyMem_Resize() instead; the older macro version, but not the
function version, silently cast away the constness.  IMO that was a wrong
thing to do, and the docs say the macro versions of PyMem_xyz are
deprecated anyway.  If somebody else is resizing const areas with the
macro spelling, they'll get a warning when they recompile now too.


Index: pymem.h
===================================================================
RCS file: /cvsroot/python/python/dist/src/Include/pymem.h,v
retrieving revision 2.12
retrieving revision 2.13
diff -C2 -d -r2.12 -r2.13
*** pymem.h	12 Apr 2002 02:39:18 -0000	2.12
--- pymem.h	12 Apr 2002 07:22:56 -0000	2.13
***************
*** 19,29 ****
     malloc), no recompilation is required for the extensions.
  
!    The macro versions trade compatibility for speed. They can be used
!    whenever there is a performance problem, but their use implies
!    recompilation of the code for each new Python release. The Python
!    core uses the macros because it *is* compiled on every upgrade.
!    This might not be the case with 3rd party extensions in a custom
!    setup (for example, a customer does not always have access to the
!    source of 3rd party deliverables). You have been warned! */
  
  /*
--- 19,29 ----
     malloc), no recompilation is required for the extensions.
  
!    The macro versions are free to trade compatibility for speed, although
!    there's no guarantee they're ever faster.  Extensions shouldn't use the
!    macro versions, as they don't gurantee binary compatibility across
!    releases.
! 
!    Do not mix calls to PyMem_xyz with calls to platform
!    malloc/realloc/calloc/free. */
  
  /*
***************
*** 32,46 ****
   */
  
- /* To make sure the interpreter is user-malloc friendly, all memory
-    APIs are implemented on top of this one. */
- 
  /* Functions */
  
! /* Function wrappers around PyMem_MALLOC and friends; useful if you
!    need to be sure that you are using the same memory allocator as
!    Python.  Note that the wrappers make sure that allocating 0 bytes
!    returns a non-NULL pointer, even if the underlying malloc
!    doesn't. Returned pointers must be checked for NULL explicitly.
!    No action is performed on failure. */
  extern DL_IMPORT(void *) PyMem_Malloc(size_t);
  extern DL_IMPORT(void *) PyMem_Realloc(void *, size_t);
--- 32,48 ----
   */
  
  /* Functions */
  
! /* Functions supplying platform-independent semantics for malloc/realloc/
!    free; useful if you need to be sure you're using the same memory
!    allocator as Python (this can be especially important on Windows, if
!    you need to make sure you're using the same MS malloc/free, and out of
!    the same heap, as the main Python DLL uses).
!    These functions make sure that allocating 0 bytes returns a distinct
!    non-NULL pointer (whenever possible -- if we're flat out of memory, NULL
!    may be returned), even if the platform malloc and realloc don't.
!    Returned pointers must be checked for NULL explicitly.  No action is
!    performed on failure (no exception is set, no warning is printed, etc).` */
! 
  extern DL_IMPORT(void *) PyMem_Malloc(size_t);
  extern DL_IMPORT(void *) PyMem_Realloc(void *, size_t);
***************
*** 50,63 ****
     no longer supported. They used to call PyErr_NoMemory() on failure. */
  
! /* Macros (override these if you want to a different malloc */
  #ifndef PyMem_MALLOC
! #define PyMem_MALLOC(n)         malloc(n)
! #define PyMem_REALLOC(p, n)     realloc((void *)(p), (n))
! #define PyMem_FREE(p)           free((void *)(p))
  #endif
  
  /*
   * Type-oriented memory interface
   * ==============================
   */
  
--- 52,78 ----
     no longer supported. They used to call PyErr_NoMemory() on failure. */
  
! /* Macros. */
  #ifndef PyMem_MALLOC
! #ifdef MALLOC_ZERO_RETURNS_NULL
! #define PyMem_MALLOC(n)         malloc((n) ? (n) : 1)
! #else
! #define PyMem_MALLOC		malloc
  #endif
  
+ /* Caution:  whether MALLOC_ZERO_RETURNS_NULL is #defined has nothing to
+    do with whether platform realloc(non-NULL, 0) normally frees the memory
+    or returns NULL.  Rather than introduce yet another config variation,
+    just make a realloc to 0 bytes act as if to 1 instead. */
+ #define PyMem_REALLOC(p, n)     realloc((p), (n) ? (n) : 1)
+ 
+ #define PyMem_FREE           	free
+ #endif	/* PyMem_MALLOC */
+ 
  /*
   * Type-oriented memory interface
   * ==============================
+  *
+  * These are carried along for historical reasons.  There's rarely a good
+  * reason to use them anymore.
   */
  
***************
*** 67,93 ****
  #define PyMem_Resize(p, type, n) \
  	( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) )
! #define PyMem_Del(p) PyMem_Free(p)
  
  /* Macros */
  #define PyMem_NEW(type, n) \
! 	( (type *) PyMem_MALLOC(_PyMem_EXTRA + (n) * sizeof(type)) )
! 
! /* See comment near MALLOC_ZERO_RETURNS_NULL in pyport.h. */
! #define PyMem_RESIZE(p, type, n)			\
! 	do {						\
! 		size_t _sum = (n) * sizeof(type);	\
! 		if (!_sum)				\
! 			_sum = 1;			\
! 		(p) = (type *)((p) ?			\
! 			       PyMem_REALLOC(p, _sum) :	\
! 			       PyMem_MALLOC(_sum));	\
! 	} while (0)
! 
! #define PyMem_DEL(p) PyMem_FREE(p)
! 
! /* PyMem_XDEL is deprecated. To avoid the call when p is NULL,
!    it is recommended to write the test explicitly in the code.
!    Note that according to ANSI C, free(NULL) has no effect. */
  
  
  #ifdef __cplusplus
--- 82,108 ----
  #define PyMem_Resize(p, type, n) \
  	( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) )
! 
! /* In order to avoid breaking old code mixing PyObject_{New, NEW} with
!    PyMem_{Del, DEL} (there was no choice about this in 1.5.2), the latter
!    have to be redirected to the object allocator. */
! /* XXX The parser module needs rework before this can be enabled. */
! #if 0
! #define PyMem_Del  PyObject_Free
! #else
! #define PyMem_Del  PyMem_Free
! #endif
  
  /* Macros */
  #define PyMem_NEW(type, n) \
! 	( (type *) PyMem_MALLOC((n) * sizeof(type)) )
! #define PyMem_RESIZE(p, type, n) \
! 	( (p) = (type *) PyMem_REALLOC((p), (n) * sizeof(type)) )
  
+ /* XXX The parser module needs rework before this can be enabled. */
+ #if 0
+ #define PyMem_DEL PyObject_FREE
+ #else
+ #define PyMem_DEL  PyMem_FREE
+ #endif
  
  #ifdef __cplusplus

Index: pyport.h
===================================================================
RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v
retrieving revision 2.46
retrieving revision 2.47
diff -C2 -d -r2.46 -r2.47
*** pyport.h	11 Apr 2002 20:44:21 -0000	2.46
--- pyport.h	12 Apr 2002 07:22:56 -0000	2.47
***************
*** 385,413 ****
  #endif
  
- 
- /************************************
-  * MALLOC COMPATIBILITY FOR pymem.h *
-  ************************************/
- 
  #ifndef DL_IMPORT       /* declarations for DLL import */
  #define DL_IMPORT(RTYPE) RTYPE
  #endif
- 
- #ifdef MALLOC_ZERO_RETURNS_NULL
- /* Allocate an extra byte if the platform malloc(0) returns NULL.
-    Caution:  this bears no relation to whether realloc(p, 0) returns NULL
-    when p != NULL.  Even on platforms where malloc(0) does not return NULL,
-    realloc(p, 0) may act like free(p) and return NULL.  Examples include
-    Windows, and Python's own obmalloc.c (as of 2-Mar-2002).  For whatever
-    reason, our docs promise that PyMem_Realloc(p, 0) won't act like
-    free(p) or return NULL, so realloc() calls may have to be hacked
-    too, but MALLOC_ZERO_RETURNS_NULL's state is irrelevant to realloc (it
-    needs a different hack).
- */
- #define _PyMem_EXTRA 1
- #else
- #define _PyMem_EXTRA 0
- #endif
- 
  
  /* If the fd manipulation macros aren't defined,
--- 385,391 ----