Vladimir Marangozov's long-awaited malloc restructuring.
For more comments, read the patches@python.org archives.
For documentation read the comments in mymalloc.h and objimpl.h.

(This is not exactly what Vladimir posted to the patches list; I've
made a few changes, and Vladimir sent me a fix in private email for a
problem that only occurs in debug mode.  I'm also holding back on his
change to main.c, which seems unnecessary to me.)
diff --git a/Objects/bufferobject.c b/Objects/bufferobject.c
index 05b1f11..72d4242 100644
--- a/Objects/bufferobject.c
+++ b/Objects/bufferobject.c
@@ -188,11 +188,11 @@
 				"size must be zero or positive");
 		return NULL;
 	}
-	b = (PyBufferObject *)malloc(sizeof(*b) + size);
+	/* PyObject_New is inlined */
+	b = (PyBufferObject *) PyObject_MALLOC(sizeof(*b) + size);
 	if ( b == NULL )
 		return PyErr_NoMemory();
-	b->ob_type = &PyBuffer_Type;
-	_Py_NewReference((PyObject *)b);
+	PyObject_INIT((PyObject *)b, &PyBuffer_Type);
 
 	b->b_base = NULL;
 	b->b_ptr = (void *)(b + 1);
@@ -212,7 +212,7 @@
 	PyBufferObject *self;
 {
 	Py_XDECREF(self->b_base);
-	free((void *)self);
+	PyObject_DEL(self);
 }
 
 static int
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 6c7dba5..bd95bc0 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -147,7 +147,7 @@
 	Py_XDECREF(op->cl_getattr);
 	Py_XDECREF(op->cl_setattr);
 	Py_XDECREF(op->cl_delattr);
-	free((ANY *)op);
+	PyObject_DEL(op);
 }
 
 static PyObject *
@@ -561,7 +561,7 @@
 #endif /* Py_TRACE_REFS */
 	Py_DECREF(inst->in_class);
 	Py_XDECREF(inst->in_dict);
-	free((ANY *)inst);
+	PyObject_DEL(inst);
 }
 
 static PyObject *
@@ -1498,8 +1498,7 @@
 	im = free_list;
 	if (im != NULL) {
 		free_list = (PyMethodObject *)(im->im_self);
-		im->ob_type = &PyMethod_Type;
-		_Py_NewReference((PyObject *)im);
+		PyObject_INIT(im, &PyMethod_Type);
 	}
 	else {
 		im = PyObject_NEW(PyMethodObject, &PyMethod_Type);
@@ -1691,8 +1690,8 @@
 PyMethod_Fini()
 {
 	while (free_list) {
-		PyMethodObject *v = free_list;
-		free_list = (PyMethodObject *)(v->im_self);
-		PyMem_DEL(v);
+		PyMethodObject *im = free_list;
+		free_list = (PyMethodObject *)(im->im_self);
+		PyObject_DEL(im);
 	}
 }
diff --git a/Objects/cobject.c b/Objects/cobject.c
index 40e8672..267ca95 100644
--- a/Objects/cobject.c
+++ b/Objects/cobject.c
@@ -151,7 +151,7 @@
 	    else
 	          (self->destructor)(self->cobject);
 	  }
-	PyMem_DEL(self);
+	PyObject_DEL(self);
 }
 
 
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index 0564942..42709ee 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -166,13 +166,14 @@
 PyComplex_FromCComplex(cval)
 	Py_complex cval;
 {
-	register PyComplexObject *op =
-		(PyComplexObject *) malloc(sizeof(PyComplexObject));
+	register PyComplexObject *op;
+
+	/* PyObject_New is inlined */
+	op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
 	if (op == NULL)
 		return PyErr_NoMemory();
-	op->ob_type = &PyComplex_Type;
+	PyObject_INIT(op, &PyComplex_Type);
 	op->cval = cval;
-	_Py_NewReference((PyObject *)op);
 	return (PyObject *) op;
 }
 
@@ -226,7 +227,7 @@
 complex_dealloc(op)
 	PyObject *op;
 {
-	PyMem_DEL(op);
+	PyObject_DEL(op);
 }
 
 
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index beab457..6e7fa3d 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -277,7 +277,7 @@
 			break;
 		}
 	}
-	newtable = (dictentry *) malloc(sizeof(dictentry) * newsize);
+	newtable = PyMem_NEW(dictentry, newsize);
 	if (newtable == NULL) {
 		PyErr_NoMemory();
 		return -1;
@@ -301,7 +301,8 @@
 		}
 	}
 
-	PyMem_XDEL(oldtable);
+	if (oldtable != NULL)
+		PyMem_DEL(oldtable);
 	return 0;
 }
 
@@ -488,8 +489,9 @@
 			Py_DECREF(ep->me_value);
 		}
 	}
-	PyMem_XDEL(mp->ma_table);
-	PyMem_DEL(mp);
+	if (mp->ma_table != NULL)
+		PyMem_DEL(mp->ma_table);
+	PyObject_DEL(mp);
 	Py_TRASHCAN_SAFE_END(mp)
 }
 
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index c8b083e..7e0979f 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -215,7 +215,7 @@
 	if (f->f_mode != NULL) {
 		Py_DECREF(f->f_mode);
 	}
-	free((char *)f);
+	PyObject_DEL(f);
 }
 
 static PyObject *
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 77ef8d0..69b66b7 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -98,9 +98,6 @@
 #define BHEAD_SIZE	8	/* Enough for a 64-bit pointer */
 #define N_FLOATOBJECTS	((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
 
-#define PyMem_MALLOC	malloc
-#define PyMem_FREE	free
-
 struct _floatblock {
 	struct _floatblock *next;
 	PyFloatObject objects[N_FLOATOBJECTS];
@@ -115,9 +112,10 @@
 fill_free_list()
 {
 	PyFloatObject *p, *q;
-	p = (PyFloatObject *)PyMem_MALLOC(sizeof(PyFloatBlock));
+	/* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */
+	p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock));
 	if (p == NULL)
-		return (PyFloatObject *)PyErr_NoMemory();
+		return (PyFloatObject *) PyErr_NoMemory();
 	((PyFloatBlock *)p)->next = block_list;
 	block_list = (PyFloatBlock *)p;
 	p = &((PyFloatBlock *)p)->objects[0];
@@ -141,11 +139,11 @@
 		if ((free_list = fill_free_list()) == NULL)
 			return NULL;
 	}
+	/* PyObject_New is inlined */
 	op = free_list;
 	free_list = (PyFloatObject *)op->ob_type;
-	op->ob_type = &PyFloat_Type;
+	PyObject_INIT(op, &PyFloat_Type);
 	op->ob_fval = fval;
-	_Py_NewReference((PyObject *)op);
 	return (PyObject *) op;
 }
 
@@ -779,7 +777,7 @@
 			}
 		}
 		else {
-			PyMem_FREE(list);
+			PyMem_FREE(list); /* XXX PyObject_FREE ??? */
 			bf++;
 		}
 		fsum += frem;
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 4c716cd..1e672bb 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -180,28 +180,27 @@
 	if (builtins != NULL && !PyDict_Check(builtins))
 		builtins = NULL;
 	if (free_list == NULL) {
+		/* PyObject_New is inlined */
 		f = (PyFrameObject *)
-			malloc(sizeof(PyFrameObject) +
-			       extras*sizeof(PyObject *));
+			PyObject_MALLOC(sizeof(PyFrameObject) +
+					extras*sizeof(PyObject *));
 		if (f == NULL)
 			return (PyFrameObject *)PyErr_NoMemory();
-		f->ob_type = &PyFrame_Type;
-		_Py_NewReference((PyObject *)f);
+		PyObject_INIT(f, &PyFrame_Type);
 	}
 	else {
 		f = free_list;
 		free_list = free_list->f_back;
 		if (f->f_nlocals + f->f_stacksize < extras) {
 			f = (PyFrameObject *)
-				realloc(f, sizeof(PyFrameObject) +
-					extras*sizeof(PyObject *));
+				PyObject_REALLOC(f, sizeof(PyFrameObject) +
+						 extras*sizeof(PyObject *));
 			if (f == NULL)
 				return (PyFrameObject *)PyErr_NoMemory();
 		}
 		else
 			extras = f->f_nlocals + f->f_stacksize;
-		f->ob_type = &PyFrame_Type;
-		_Py_NewReference((PyObject *)f);
+		PyObject_INIT(f, &PyFrame_Type);
 	}
 	if (builtins == NULL) {
 		/* No builtins!  Make up a minimal one. */
@@ -376,6 +375,6 @@
 	while (free_list != NULL) {
 		PyFrameObject *f = free_list;
 		free_list = free_list->f_back;
-		PyMem_DEL(f);
+		PyObject_DEL(f);
 	}
 }
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 562935c..a5e15cc 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -191,7 +191,7 @@
 	Py_DECREF(op->func_name);
 	Py_XDECREF(op->func_defaults);
 	Py_XDECREF(op->func_doc);
-	PyMem_DEL(op);
+	PyObject_DEL(op);
 }
 
 static PyObject*
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 0c8eefc..79435a9 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -94,9 +94,6 @@
 #define BHEAD_SIZE	8	/* Enough for a 64-bit pointer */
 #define N_INTOBJECTS	((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))
 
-#define PyMem_MALLOC	malloc
-#define PyMem_FREE	free
-
 struct _intblock {
 	struct _intblock *next;
 	PyIntObject objects[N_INTOBJECTS];
@@ -111,9 +108,10 @@
 fill_free_list()
 {
 	PyIntObject *p, *q;
-	p = (PyIntObject *)PyMem_MALLOC(sizeof(PyIntBlock));
+	/* XXX Int blocks escape the object heap. Use PyObject_MALLOC ??? */
+	p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
 	if (p == NULL)
-		return (PyIntObject *)PyErr_NoMemory();
+		return (PyIntObject *) PyErr_NoMemory();
 	((PyIntBlock *)p)->next = block_list;
 	block_list = (PyIntBlock *)p;
 	p = &((PyIntBlock *)p)->objects[0];
@@ -164,11 +162,11 @@
 		if ((free_list = fill_free_list()) == NULL)
 			return NULL;
 	}
+	/* PyObject_New is inlined */
 	v = free_list;
 	free_list = (PyIntObject *)v->ob_type;
-	v->ob_type = &PyInt_Type;
+	PyObject_INIT(v, &PyInt_Type);
 	v->ob_ival = ival;
-	_Py_NewReference((PyObject *)v);
 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
 	if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
 		/* save this one for a following allocation */
@@ -933,7 +931,7 @@
 			}
 		}
 		else {
-			PyMem_FREE(list);
+			PyMem_FREE(list); /* XXX PyObject_FREE ??? */
 			bf++;
 		}
 		isum += irem;
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 005d709..f70d19b 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -70,7 +70,8 @@
 	if (nbytes / sizeof(PyObject *) != (size_t)size) {
 		return PyErr_NoMemory();
 	}
-	op = (PyListObject *) malloc(sizeof(PyListObject));
+	/* PyObject_NewVar is inlined */
+	op = (PyListObject *) PyObject_MALLOC(sizeof(PyListObject));
 	if (op == NULL) {
 		return PyErr_NoMemory();
 	}
@@ -78,17 +79,15 @@
 		op->ob_item = NULL;
 	}
 	else {
-		op->ob_item = (PyObject **) malloc(nbytes);
+		op->ob_item = (PyObject **) PyMem_MALLOC(nbytes);
 		if (op->ob_item == NULL) {
-			free((ANY *)op);
+			PyObject_FREE(op);
 			return PyErr_NoMemory();
 		}
 	}
-	op->ob_type = &PyList_Type;
-	op->ob_size = size;
+	PyObject_INIT_VAR(op, &PyList_Type, size);
 	for (i = 0; i < size; i++)
 		op->ob_item[i] = NULL;
-	_Py_NewReference((PyObject *)op);
 	return (PyObject *) op;
 }
 
@@ -225,9 +224,9 @@
 		while (--i >= 0) {
 			Py_XDECREF(op->ob_item[i]);
 		}
-		free((ANY *)op->ob_item);
+		PyMem_FREE(op->ob_item);
 	}
-	free((ANY *)op);
+	PyObject_DEL(op);
 	Py_TRASHCAN_SAFE_END(op)
 }
 
@@ -501,7 +500,8 @@
 	else { /* Insert d items; recycle ihigh-ilow items */
 		NRESIZE(item, PyObject *, a->ob_size + d);
 		if (item == NULL) {
-			PyMem_XDEL(recycle);
+			if (recycle != NULL)
+				PyMem_DEL(recycle);
 			PyErr_NoMemory();
 			return -1;
 		}
diff --git a/Objects/longobject.c b/Objects/longobject.c
index a9ce6f3..4bf89d9 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -995,7 +995,7 @@
 long_dealloc(v)
 	PyObject *v;
 {
-	PyMem_DEL(v);
+	PyObject_DEL(v);
 }
 
 static PyObject *
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 5c69744..8b67a87 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -46,8 +46,7 @@
 	op = free_list;
 	if (op != NULL) {
 		free_list = (PyCFunctionObject *)(op->m_self);
-		op->ob_type = &PyCFunction_Type;
-		_Py_NewReference((PyObject *)op);
+		PyObject_INIT(op, &PyCFunction_Type);
 	}
 	else {
 		op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type);
@@ -288,6 +287,6 @@
 	while (free_list) {
 		PyCFunctionObject *v = free_list;
 		free_list = (PyCFunctionObject *)(v->m_self);
-		PyMem_DEL(v);
+		PyObject_DEL(v);
 	}
 }
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index 7dfca73..808e27a 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -170,7 +170,7 @@
 		_PyModule_Clear((PyObject *)m);
 		Py_DECREF(m->md_dict);
 	}
-	free((char *)m);
+	PyObject_DEL(m);
 }
 
 static PyObject *
diff --git a/Objects/object.c b/Objects/object.c
index ed276e2..6195479 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -112,50 +112,68 @@
 }
 #endif
 
-#ifndef MS_COREDLL
 PyObject *
-_PyObject_New(tp)
-	PyTypeObject *tp;
-#else
-PyObject *
-_PyObject_New(tp,op)
-	PyTypeObject *tp;
+PyObject_Init(op, tp)
 	PyObject *op;
-#endif
+	PyTypeObject *tp;
 {
-#ifndef MS_COREDLL
-	PyObject *op = (PyObject *) malloc(tp->tp_basicsize);
-#endif
-	if (op == NULL)
-		return PyErr_NoMemory();
+	if (op == NULL) {
+		PyErr_SetString(PyExc_SystemError,
+				"NULL object passed to PyObject_Init");
+		return op;
+  	}
+	/* Any changes should be reflected in PyObject_INIT (objimpl.h) */
 	op->ob_type = tp;
 	_Py_NewReference(op);
 	return op;
 }
 
-#ifndef MS_COREDLL
+PyVarObject *
+PyObject_InitVar(op, tp, size)
+	PyVarObject *op;
+	PyTypeObject *tp;
+	int size;
+{
+	if (op == NULL) {
+		PyErr_SetString(PyExc_SystemError,
+				"NULL object passed to PyObject_InitVar");
+		return op;
+	}
+	/* Any changes should be reflected in PyObject_INIT_VAR */
+	op->ob_size = size;
+	op->ob_type = tp;
+	_Py_NewReference((PyObject *)op);
+	return op;
+}
+
+PyObject *
+_PyObject_New(tp)
+	PyTypeObject *tp;
+{
+	PyObject *op;
+	op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp));
+	if (op == NULL)
+		return PyErr_NoMemory();
+	return PyObject_INIT(op, tp);
+}
+
 PyVarObject *
 _PyObject_NewVar(tp, size)
 	PyTypeObject *tp;
 	int size;
-#else
-PyVarObject *
-_PyObject_NewVar(tp, size, op)
-	PyTypeObject *tp;
-	int size;
-	PyVarObject *op;
-#endif
 {
-#ifndef MS_COREDLL
-	PyVarObject *op = (PyVarObject *)
-		malloc(tp->tp_basicsize + size * tp->tp_itemsize);
-#endif
+	PyVarObject *op;
+	op = (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE(tp, size));
 	if (op == NULL)
 		return (PyVarObject *)PyErr_NoMemory();
-	op->ob_type = tp;
-	op->ob_size = size;
-	_Py_NewReference((PyObject *)op);
-	return op;
+	return PyObject_INIT_VAR(op, tp, size);
+}
+
+void
+_PyObject_Del(op)
+	PyObject *op;
+{
+	PyObject_FREE(op);
 }
 
 int
@@ -888,54 +906,7 @@
 int (*_Py_abstract_hack) Py_FPROTO((PyObject *)) = &PyObject_Length;
 
 
-/* Malloc wrappers (see mymalloc.h) */
-
-/* The Py_{Malloc,Realloc} wrappers call PyErr_NoMemory() on failure */
-
-ANY *
-Py_Malloc(nbytes)
-	size_t nbytes;
-{
-	ANY *p;
-#if _PyMem_EXTRA > 0
-	if (nbytes == 0)
-		nbytes = _PyMem_EXTRA;
-#endif
-	p = malloc(nbytes);
-	if (p != NULL)
-		return p;
-	else {
-		PyErr_NoMemory();
-		return NULL;
-	}
-}
-
-ANY *
-Py_Realloc(p, nbytes)
-	ANY *p;
-	size_t nbytes;
-{
-#if _PyMem_EXTRA > 0
-	if (nbytes == 0)
-		nbytes = _PyMem_EXTRA;
-#endif
-	p = realloc(p, nbytes);
-	if (p != NULL)
-		return p;
-	else {
-		PyErr_NoMemory();
-		return NULL;
-	}
-}
-
-void
-Py_Free(p)
-	ANY *p;
-{
-	free(p);
-}
-
-/* The PyMem_{Malloc,Realloc} wrappers don't call anything on failure */
+/* Python's malloc wrappers (see mymalloc.h) */
 
 ANY *
 PyMem_Malloc(nbytes)
@@ -945,7 +916,7 @@
 	if (nbytes == 0)
 		nbytes = _PyMem_EXTRA;
 #endif
-	return malloc(nbytes);
+	return PyMem_MALLOC(nbytes);
 }
 
 ANY *
@@ -957,14 +928,39 @@
 	if (nbytes == 0)
 		nbytes = _PyMem_EXTRA;
 #endif
-	return realloc(p, nbytes);
+	return PyMem_REALLOC(p, nbytes);
 }
 
 void
 PyMem_Free(p)
 	ANY *p;
 {
-	free(p);
+	PyMem_FREE(p);
+}
+
+
+/* Python's object malloc wrappers (see objimpl.h) */
+
+ANY *
+PyObject_Malloc(nbytes)
+	size_t nbytes;
+{
+	return PyObject_MALLOC(nbytes);
+}
+
+ANY *
+PyObject_Realloc(p, nbytes)
+	ANY *p;
+	size_t nbytes;
+{
+	return PyObject_REALLOC(p, nbytes);
+}
+
+void
+PyObject_Free(p)
+	ANY *p;
+{
+	PyObject_FREE(p);
 }
 
 
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index c603ac9..807cf51 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -61,7 +61,7 @@
 range_dealloc(r)
 	rangeobject *r;
 {
-	PyMem_DEL(r);
+	PyObject_DEL(r);
 }
 
 static PyObject *
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
index a232296..eb4972b 100644
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -57,8 +57,7 @@
 	PyObject *stop;
 	PyObject *step;
 {
-	PySliceObject *obj =
-		(PySliceObject *) PyObject_NEW(PySliceObject, &PySlice_Type);
+	PySliceObject *obj = PyObject_NEW(PySliceObject, &PySlice_Type);
 
 	if (step == NULL) step = Py_None;
 	Py_INCREF(step);
@@ -115,7 +114,7 @@
 	Py_DECREF(r->step);
 	Py_DECREF(r->start);
 	Py_DECREF(r->stop);
-	PyMem_DEL(r);
+	PyObject_DEL(r);
 }
 
 static PyObject *
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 5b5ed9c..288f26e 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -92,19 +92,19 @@
 		return (PyObject *)op;
 	}
 #endif /* DONT_SHARE_SHORT_STRINGS */
+
+	/* PyObject_NewVar is inlined */
 	op = (PyStringObject *)
-		malloc(sizeof(PyStringObject) + size * sizeof(char));
+		PyObject_MALLOC(sizeof(PyStringObject) + size * sizeof(char));
 	if (op == NULL)
 		return PyErr_NoMemory();
-	op->ob_type = &PyString_Type;
-	op->ob_size = size;
+	PyObject_INIT_VAR(op, &PyString_Type, size);
 #ifdef CACHE_HASH
 	op->ob_shash = -1;
 #endif
 #ifdef INTERN_STRINGS
 	op->ob_sinterned = NULL;
 #endif
-	_Py_NewReference((PyObject *)op);
 	if (str != NULL)
 		memcpy(op->ob_sval, str, size);
 	op->ob_sval[size] = '\0';
@@ -142,19 +142,19 @@
 		return (PyObject *)op;
 	}
 #endif /* DONT_SHARE_SHORT_STRINGS */
+
+	/* PyObject_NewVar is inlined */
 	op = (PyStringObject *)
-		malloc(sizeof(PyStringObject) + size * sizeof(char));
+		PyObject_MALLOC(sizeof(PyStringObject) + size * sizeof(char));
 	if (op == NULL)
 		return PyErr_NoMemory();
-	op->ob_type = &PyString_Type;
-	op->ob_size = size;
+	PyObject_INIT_VAR(op, &PyString_Type, size);
 #ifdef CACHE_HASH
 	op->ob_shash = -1;
 #endif
 #ifdef INTERN_STRINGS
 	op->ob_sinterned = NULL;
 #endif
-	_Py_NewReference((PyObject *)op);
 	strcpy(op->ob_sval, str);
 #ifndef DONT_SHARE_SHORT_STRINGS
 	if (size == 0) {
@@ -172,7 +172,7 @@
 string_dealloc(op)
 	PyObject *op;
 {
-	PyMem_DEL(op);
+	PyObject_DEL(op);
 }
 
 int
@@ -307,19 +307,18 @@
 		return (PyObject *)a;
 	}
 	size = a->ob_size + b->ob_size;
+	/* PyObject_NewVar is inlined */
 	op = (PyStringObject *)
-		malloc(sizeof(PyStringObject) + size * sizeof(char));
+		PyObject_MALLOC(sizeof(PyStringObject) + size * sizeof(char));
 	if (op == NULL)
 		return PyErr_NoMemory();
-	op->ob_type = &PyString_Type;
-	op->ob_size = size;
+	PyObject_INIT_VAR(op, &PyString_Type, size);
 #ifdef CACHE_HASH
 	op->ob_shash = -1;
 #endif
 #ifdef INTERN_STRINGS
 	op->ob_sinterned = NULL;
 #endif
-	_Py_NewReference((PyObject *)op);
 	memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
 	memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
 	op->ob_sval[size] = '\0';
@@ -342,19 +341,18 @@
 		Py_INCREF(a);
 		return (PyObject *)a;
 	}
+	/* PyObject_NewVar is inlined */
 	op = (PyStringObject *)
-		malloc(sizeof(PyStringObject) + size * sizeof(char));
+		PyObject_MALLOC(sizeof(PyStringObject) + size * sizeof(char));
 	if (op == NULL)
 		return PyErr_NoMemory();
-	op->ob_type = &PyString_Type;
-	op->ob_size = size;
+	PyObject_INIT_VAR(op, &PyString_Type, size);
 #ifdef CACHE_HASH
 	op->ob_shash = -1;
 #endif
 #ifdef INTERN_STRINGS
 	op->ob_sinterned = NULL;
 #endif
-	_Py_NewReference((PyObject *)op);
 	for (i = 0; i < size; i += a->ob_size)
 		memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
 	op->ob_sval[size] = '\0';
@@ -1498,7 +1496,7 @@
 		goto return_same;
 	new_len = len + nfound*(sub_len - pat_len);
 
-	new_s = (char *)malloc(new_len);
+	new_s = (char *)PyMem_MALLOC(new_len);
 	if (new_s == NULL) return NULL;
 
 	*out_len = new_len;
@@ -1593,7 +1591,7 @@
 	}
 	else {
 		new = PyString_FromStringAndSize(new_s, out_len);
-		free(new_s);
+		PyMem_FREE(new_s);
 	}
 	return new;
 }
@@ -2273,10 +2271,10 @@
 #endif
 	_Py_ForgetReference(v);
 	*pv = (PyObject *)
-		realloc((char *)v,
+		PyObject_REALLOC((char *)v,
 			sizeof(PyStringObject) + newsize * sizeof(char));
 	if (*pv == NULL) {
-		PyMem_DEL(v);
+		PyObject_DEL(v);
 		PyErr_NoMemory();
 		return -1;
 	}
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index d1627a9..d5d6a07 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -80,10 +80,12 @@
 #ifdef COUNT_ALLOCS
 		fast_tuple_allocs++;
 #endif
+		/* PyObject_InitVar is inlined */
 #ifdef Py_TRACE_REFS
-		op->ob_type = &PyTuple_Type;
 		op->ob_size = size;
+		op->ob_type = &PyTuple_Type;
 #endif
+		_Py_NewReference((PyObject *)op);
 	}
 	else
 #endif
@@ -96,17 +98,15 @@
 		{
 			return PyErr_NoMemory();
 		}
-		;
-		op = (PyTupleObject *) malloc(nbytes);
+		/* PyObject_NewVar is inlined */
+		op = (PyTupleObject *) PyObject_MALLOC(nbytes);
 		if (op == NULL)
 			return PyErr_NoMemory();
 
-		op->ob_type = &PyTuple_Type;
-		op->ob_size = size;
+		PyObject_INIT_VAR(op, &PyTuple_Type, size);
 	}
 	for (i = 0; i < size; i++)
 		op->ob_item[i] = NULL;
-	_Py_NewReference((PyObject *)op);
 #if MAXSAVESIZE > 0
 	if (size == 0) {
 		free_tuples[0] = op;
@@ -193,7 +193,7 @@
 		}
 #endif
 	}
-	free((ANY *)op);
+	PyObject_DEL(op);
 done:
 	Py_TRASHCAN_SAFE_END(op)
 }
@@ -530,11 +530,11 @@
 #endif		
 	{
 		sv = (PyTupleObject *)
-			realloc((char *)v,
+			PyObject_REALLOC((char *)v,
 				sizeof(PyTupleObject) + newsize * sizeof(PyObject *));
 		*pv = (PyObject *) sv;
 		if (sv == NULL) {
-			PyMem_DEL(v);
+			PyObject_DEL(v);
 			PyErr_NoMemory();
 			return -1;
 		}
@@ -569,7 +569,7 @@
 		while (p) {
 			q = p;
 			p = (PyTupleObject *)(p->ob_item[0]);
-			PyMem_DEL(q);
+			PyObject_DEL(q);
 		}
 	}
 #endif
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 7a68dd4..601b987 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -200,14 +200,13 @@
         unicode = unicode_freelist;
         unicode_freelist = *(PyUnicodeObject **)unicode_freelist;
         unicode_freelist_size--;
-        unicode->ob_type = &PyUnicode_Type;
-        _Py_NewReference((PyObject *)unicode);
+	PyObject_INIT(unicode, &PyUnicode_Type);
 	if (unicode->str) {
 	    /* Keep-Alive optimization: we only upsize the buffer,
 	       never downsize it. */
 	    if ((unicode->length < length) &&
 		_PyUnicode_Resize(unicode, length)) {
-		free(unicode->str);
+		PyMem_DEL(unicode->str);
 		goto onError;
 	    }
 	}
@@ -233,7 +232,7 @@
 
  onError:
     _Py_ForgetReference((PyObject *)unicode);
-    PyMem_DEL(unicode);
+    PyObject_DEL(unicode);
     return NULL;
 }
 
@@ -243,7 +242,7 @@
     if (unicode_freelist_size < MAX_UNICODE_FREELIST_SIZE) {
         /* Keep-Alive optimization */
 	if (unicode->length >= KEEPALIVE_SIZE_LIMIT) {
-	    free(unicode->str);
+	    PyMem_DEL(unicode->str);
 	    unicode->str = NULL;
 	    unicode->length = 0;
 	}
@@ -257,9 +256,9 @@
         unicode_freelist_size++;
     }
     else {
-	free(unicode->str);
+	PyMem_DEL(unicode->str);
 	Py_XDECREF(unicode->utf8str);
-        PyMem_DEL(unicode);
+	PyObject_DEL(unicode);
     }
 }
 
@@ -4662,9 +4661,9 @@
 	PyUnicodeObject *v = u;
 	u = *(PyUnicodeObject **)u;
 	if (v->str)
-	    free(v->str);
+	    PyMem_DEL(v->str);
 	Py_XDECREF(v->utf8str);
-	free(v);
+	PyObject_DEL(v);
     }
     Py_XDECREF(unicode_empty);
 }
diff --git a/Objects/xxobject.c b/Objects/xxobject.c
index c5b518f..91c9833 100644
--- a/Objects/xxobject.c
+++ b/Objects/xxobject.c
@@ -71,7 +71,7 @@
 	xxobject *xp;
 {
 	Py_XDECREF(xp->x_attr);
-	PyMem_DEL(xp);
+	PyObject_DEL(xp);
 }
 
 static PyObject *