[Python-checkins] CVS: python/dist/src/Include objimpl.h,2.41,2.42

Tim Peters tim_one@users.sourceforge.net
Sat, 06 Oct 2001 20:54:53 -0700


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

Modified Files:
	objimpl.h 
Log Message:
Guido suggests, and I agree, to insist that SIZEOF_VOID_P be a power of 2.
This simplifies the rounding in _PyObject_VAR_SIZE, allows to restore the
pre-rounding calling sequence, and allows some nice little simplifications
in its callers.  I'm still making it return a size_t, though.


Index: objimpl.h
===================================================================
RCS file: /cvsroot/python/python/dist/src/Include/objimpl.h,v
retrieving revision 2.41
retrieving revision 2.42
diff -C2 -d -r2.41 -r2.42
*** objimpl.h	2001/10/06 21:27:34	2.41
--- objimpl.h	2001/10/07 03:54:51	2.42
***************
*** 174,211 ****
  #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
  
! /* _PyObject_VAR_SIZE computes the amount of memory allocated for a vrbl-
!   size object with nitems items, exclusive of gc overhead (if any).  The
!   value is rounded up to the closest multiple of sizeof(void *), in order
!   to ensure that pointer fields at the end of the object are correctly
!   aligned for the platform (this is of special importance for subclasses
!   of, e.g., str or long, so that pointers can be stored after the embedded
!   data).
! 
!   Note that there's no memory wastage in doing this, as malloc has to
!   return (at worst) pointer-aligned memory anyway
  
!   However, writing the macro to *return* the result is clumsy due to the
!   calculations needed.  Instead you must pass the result lvalue as the first
!   argument, and it should be of type size_t (both because that's the
!   correct conceptual type, and because using an unsigned type allows the
!   compiler to generate faster code for the mod computation inside the
!   macro).
  */
! #define _PyObject_VAR_SIZE(result, typeobj, nitems)			\
! 	do {								\
!     		size_t mod;						\
! 		(result) = (size_t) (typeobj)->tp_basicsize;		\
! 		(result) += (size_t) ((nitems)*(typeobj)->tp_itemsize);	\
! 		mod = (result) % SIZEOF_VOID_P;				\
! 		if (mod)						\
! 			(result) += SIZEOF_VOID_P - mod;		\
!     	} while(0)
  
  #define PyObject_NEW(type, typeobj) \
  ( (type *) PyObject_Init( \
  	(PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) )
  
! #define PyObject_NEW_VAR(type, typeobj, nitems) \
! 	((type *) _PyObject_NewVar(typeobj, nitems))
  
  #define PyObject_DEL(op) PyObject_FREE(op)
--- 174,207 ----
  #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
  
! /* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
!    vrbl-size object with nitems items, exclusive of gc overhead (if any).  The
!    value is rounded up to the closest multiple of sizeof(void *), in order to
!    ensure that pointer fields at the end of the object are correctly aligned
!    for the platform (this is of special importance for subclasses of, e.g.,
!    str or long, so that pointers can be stored after the embedded data).
  
!    Note that there's no memory wastage in doing this, as malloc has to
!    return (at worst) pointer-aligned memory anyway.
  */
! #if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0
! #   error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
! #endif
  
+ #define _PyObject_VAR_SIZE(typeobj, nitems)	\
+ 	(size_t)				\
+ 	( ( (typeobj)->tp_basicsize +		\
+ 	    (nitems)*(typeobj)->tp_itemsize +	\
+ 	    (SIZEOF_VOID_P - 1)			\
+ 	  ) & ~(SIZEOF_VOID_P - 1)		\
+ 	)
+ 
  #define PyObject_NEW(type, typeobj) \
  ( (type *) PyObject_Init( \
  	(PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) )
  
! #define PyObject_NEW_VAR(type, typeobj, n) \
! ( (type *) PyObject_InitVar( \
!       (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE((typeobj),(n)) ),\
!       (typeobj), (n)) )
  
  #define PyObject_DEL(op) PyObject_FREE(op)