]> granicus.if.org Git - python/commitdiff
Repaired the debug Windows deaths in test_descr, by allocating enough
authorTim Peters <tim.peters@gmail.com>
Sat, 6 Oct 2001 19:04:01 +0000 (19:04 +0000)
committerTim Peters <tim.peters@gmail.com>
Sat, 6 Oct 2001 19:04:01 +0000 (19:04 +0000)
pad memory to properly align the __dict__ pointer in all cases.

gcmodule.c/objimpl.h, _PyObject_GC_Malloc:
+ Added a "padding" argument so that this flavor of malloc can allocate
  enough bytes for alignment padding (it can't know this is needed, but
  its callers do).

typeobject.c, PyType_GenericAlloc:
+ Allocated enough bytes to align the __dict__ pointer.
+ Sped and simplified the round-up-to-PTRSIZE logic.
+ Added blank lines so I could parse the if/else blocks <0.7 wink>.

Include/objimpl.h
Modules/gcmodule.c
Objects/typeobject.c

index 0fd66526a7089f2b6636a0ef008b4042d2cafa23..e24d42eae0e1c806c2e38e087e74aefc94b8de7f 100644 (file)
@@ -230,7 +230,8 @@ extern DL_IMPORT(void) _PyObject_Del(PyObject *);
 #define PyObject_IS_GC(o) (PyType_IS_GC((o)->ob_type) && \
        ((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(PyObject *) _PyObject_GC_Malloc(PyTypeObject *,
+                                       int nitems, size_t padding);
 extern DL_IMPORT(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, int);
 
 #define PyObject_GC_Resize(type, op, n) \
index 43a7bf131f6b87751ab3e986bb19e532673641ca..349ba6a630ca7c900b2f98472df587a3bde292fd 100644 (file)
@@ -798,13 +798,14 @@ _PyObject_GC_UnTrack(PyObject *op)
 }
 
 PyObject *
-_PyObject_GC_Malloc(PyTypeObject *tp, int size)
+_PyObject_GC_Malloc(PyTypeObject *tp, int nitems, size_t padding)
 {
        PyObject *op;
 #ifdef WITH_CYCLE_GC
-       const size_t nbytes = sizeof(PyGC_Head) +
-                             (size_t)_PyObject_VAR_SIZE(tp, size);
-       PyGC_Head *g = PyObject_MALLOC(nbytes);                                         
+       const size_t basic = (size_t)_PyObject_VAR_SIZE(tp, nitems);
+       const size_t nbytes = sizeof(PyGC_Head) + basic + padding;
+
+       PyGC_Head *g = PyObject_MALLOC(nbytes);
        if (g == NULL)
                return (PyObject *)PyErr_NoMemory();
        g->gc_next = NULL;
@@ -820,7 +821,7 @@ _PyObject_GC_Malloc(PyTypeObject *tp, int size)
        }
        op = FROM_GC(g);
 #else
-       op = PyObject_MALLOC(_PyObject_VAR_SIZE(tp, size));
+       op = PyObject_MALLOC(_PyObject_VAR_SIZE(tp, nitems) + padding);
        if (op == NULL)
                return (PyObject *)PyErr_NoMemory();
 
@@ -831,14 +832,14 @@ _PyObject_GC_Malloc(PyTypeObject *tp, int size)
 PyObject *
 _PyObject_GC_New(PyTypeObject *tp)
 {
-       PyObject *op = _PyObject_GC_Malloc(tp, 0);
+       PyObject *op = _PyObject_GC_Malloc(tp, 0, 0);
        return PyObject_INIT(op, tp);
 }
 
 PyVarObject *
 _PyObject_GC_NewVar(PyTypeObject *tp, int size)
 {
-       PyVarObject *op = (PyVarObject *) _PyObject_GC_Malloc(tp, size);
+       PyVarObject *op = (PyVarObject *) _PyObject_GC_Malloc(tp, size, 0);
        return PyObject_INIT_VAR(op, tp, size);
 }
 
index fed6c438faeac2d22adc0d1061d602fa2621f29e..59ec5882942eb554e21bd247d32de11711e1fd8b 100644 (file)
@@ -192,32 +192,42 @@ PyType_GenericAlloc(PyTypeObject *type, int nitems)
 {
 #define PTRSIZE (sizeof(PyObject *))
 
-       int size;
+       size_t size = (size_t)_PyObject_VAR_SIZE(type, nitems);
+       size_t padding = 0;
        PyObject *obj;
 
-       /* Inline PyObject_New() so we can zero the memory */
-       size = _PyObject_VAR_SIZE(type, nitems);
-       /* Round up size, if necessary, so we fully zero out __dict__ */
-       if (type->tp_itemsize % PTRSIZE != 0) {
-               size += PTRSIZE - 1;
-               size /= PTRSIZE;
-               size *= PTRSIZE;
-       }
-       if (PyType_IS_GC(type)) {
-               obj = _PyObject_GC_Malloc(type, nitems);
+       /* Round up size, if necessary, so that the __dict__ pointer
+          following the variable part is properly aligned for the platform.
+          This is needed only for types with a vrbl number of items
+          before the __dict__ pointer == types that record the dict offset
+          as a negative offset from the end of the object.  If tp_dictoffset
+          is 0, there is no __dict__; if positive, tp_dict was declared in a C
+          struct so the compiler already took care of aligning it. */
+        if (type->tp_dictoffset < 0) {
+               padding = PTRSIZE - size % PTRSIZE;
+               if (padding == PTRSIZE)
+                       padding = 0;
+               size += padding;
        }
-       else {
+
+       if (PyType_IS_GC(type))
+               obj = _PyObject_GC_Malloc(type, nitems, padding);
+       else
                obj = PyObject_MALLOC(size);
-       }
+
        if (obj == NULL)
                return PyErr_NoMemory();
+
        memset(obj, '\0', size);
+
        if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
                Py_INCREF(type);
+
        if (type->tp_itemsize == 0)
                PyObject_INIT(obj, type);
        else
                (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);
+
        if (PyType_IS_GC(type))
                _PyObject_GC_TRACK(obj);
        return obj;