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

Tim Peters tim_one@users.sourceforge.net
Sat, 06 Oct 2001 14:27:36 -0700


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

Modified Files:
	objimpl.h 
Log Message:
_PyObject_VAR_SIZE:  always round up to a multiple-of-pointer-size value.
As Guido suggested, this makes the new subclassing code substantially
simpler.  But the mechanics of doing it w/ C macro semantics are a mess,
and _PyObject_VAR_SIZE has a new calling sequence now.

Question:  The PyObject_NEW_VAR macro appears to be part of the public API.
Regardless of what it expands to, the notion that it has to round up the
memory it allocates is new, and extensions containing the old
PyObject_NEW_VAR macro expansion (which was embedded in the
PyObject_NEW_VAR expansion) won't do this rounding.  But the rounding
isn't actually *needed* except for new-style instances with dict pointers
after a variable-length blob of embedded data.  So my guess is that we do
not need to bump the API version for this (as the rounding isn't needed
for anything an extension can do unless it's recompiled anyway).  What's
your guess?


Index: objimpl.h
===================================================================
RCS file: /cvsroot/python/python/dist/src/Include/objimpl.h,v
retrieving revision 2.40
retrieving revision 2.41
diff -C2 -d -r2.40 -r2.41
*** objimpl.h	2001/10/06 19:04:00	2.40
--- objimpl.h	2001/10/06 21:27:34	2.41
***************
*** 57,61 ****
  recommended to use PyObject_{New, NewVar, Del}. */
  
! /* 
   * Core object memory allocator
   * ============================
--- 57,61 ----
  recommended to use PyObject_{New, NewVar, Del}. */
  
! /*
   * Core object memory allocator
   * ============================
***************
*** 64,68 ****
  /* The purpose of the object allocator is to make the distinction
     between "object memory" and the rest within the Python heap.
!    
     Object memory is the one allocated by PyObject_{New, NewVar}, i.e.
     the one that holds the object's representation defined by its C
--- 64,68 ----
  /* The purpose of the object allocator is to make the distinction
     between "object memory" and the rest within the Python heap.
! 
     Object memory is the one allocated by PyObject_{New, NewVar}, i.e.
     the one that holds the object's representation defined by its C
***************
*** 173,186 ****
  
  #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
! #define _PyObject_VAR_SIZE(typeobj, n) \
! 	( (typeobj)->tp_basicsize + (n) * (typeobj)->tp_itemsize )
  
  #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)
--- 173,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)
***************
*** 231,236 ****
  	((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o)))
  
! extern DL_IMPORT(PyObject *) _PyObject_GC_Malloc(PyTypeObject *,
! 					int nitems, size_t padding);
  extern DL_IMPORT(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, int);
  
--- 256,260 ----
  	((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o)))
  
! extern DL_IMPORT(PyObject *) _PyObject_GC_Malloc(PyTypeObject *, int);
  extern DL_IMPORT(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, int);
  
***************
*** 277,281 ****
  #define PyObject_GC_Track(op) _PyObject_GC_Track((PyObject *)op)
  #define PyObject_GC_UnTrack(op) _PyObject_GC_UnTrack((PyObject *)op)
! 	
  
  #define PyObject_GC_New(type, typeobj) \
--- 301,305 ----
  #define PyObject_GC_Track(op) _PyObject_GC_Track((PyObject *)op)
  #define PyObject_GC_UnTrack(op) _PyObject_GC_UnTrack((PyObject *)op)
! 
  
  #define PyObject_GC_New(type, typeobj) \