From ead64f317be6eae7cdff9074659f8140aea3c4d5 Mon Sep 17 00:00:00 2001
From: Jan Wieck <JanWieck@Yahoo.com>
Date: Sat, 6 Feb 1999 16:50:34 +0000
Subject: [PATCH] New alloc set code using a memory block pool for small
 allocations.

Jan
---
 src/backend/catalog/pg_type.c      |    9 +-
 src/backend/executor/execMain.c    |    4 +-
 src/backend/nodes/Makefile         |    6 +-
 src/backend/nodes/freefuncs.c      | 1381 ++++++++++++++++++++++++++++
 src/backend/utils/mmgr/aset.c      |  377 ++++----
 src/backend/utils/mmgr/mcxt.c      |   11 +-
 src/backend/utils/mmgr/palloc.c    |   90 +-
 src/backend/utils/mmgr/portalmem.c |   21 +-
 src/include/nodes/memnodes.h       |   10 +-
 src/include/nodes/nodes.h          |    7 +-
 src/include/utils/memutils.h       |   32 +-
 src/include/utils/palloc.h         |   26 +-
 src/include/utils/portal.h         |    6 +-
 13 files changed, 1666 insertions(+), 314 deletions(-)
 create mode 100644 src/backend/nodes/freefuncs.c

diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 17b9574001..7336de8896 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.33 1999/02/03 21:15:56 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.34 1999/02/06 16:50:22 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,7 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
 {
 	HeapScanDesc scan;
 	HeapTuple	tup;
+	Oid			typoid;
 
 	static ScanKeyData typeKey[1] = {
 		{0, Anum_pg_type_typname, F_NAMEEQ}
@@ -96,10 +97,12 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
 	 *	oid, which is the oid of the type.
 	 * ----------------
 	 */
-	heap_endscan(scan);
 	*defined = (bool) ((Form_pg_type) GETSTRUCT(tup))->typisdefined;
+	typoid = tup->t_data->t_oid;
 
-	return tup->t_data->t_oid;
+	heap_endscan(scan);
+
+	return typoid;
 }
 
 /* ----------------------------------------------------------------
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 60aec3e488..51478f0625 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.70 1999/02/02 03:44:23 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.71 1999/02/06 16:50:23 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1492,7 +1492,7 @@ ExecRelCheck(Relation rel, HeapTuple tuple)
 
 		res = ExecQual(qual, econtext);
 
-		pfree(qual);
+		freeObject(qual);
 
 		if (!res)
 			return check[i].ccname;
diff --git a/src/backend/nodes/Makefile b/src/backend/nodes/Makefile
index 7e34521f6b..0e50980c28 100644
--- a/src/backend/nodes/Makefile
+++ b/src/backend/nodes/Makefile
@@ -4,7 +4,7 @@
 #    Makefile for nodes
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/nodes/Makefile,v 1.6 1998/04/06 00:23:00 momjian Exp $
+#    $Header: /cvsroot/pgsql/src/backend/nodes/Makefile,v 1.7 1999/02/06 16:50:24 wieck Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -14,8 +14,8 @@ include ../../Makefile.global
 CFLAGS += -I..
 
 OBJS = nodeFuncs.o nodes.o list.o \
-       copyfuncs.o equalfuncs.o makefuncs.o outfuncs.o readfuncs.o \
-       print.o read.o
+       copyfuncs.o equalfuncs.o freefuncs.o makefuncs.o outfuncs.o \
+       readfuncs.o print.o read.o
 
 all: SUBSYS.o
 
diff --git a/src/backend/nodes/freefuncs.c b/src/backend/nodes/freefuncs.c
new file mode 100644
index 0000000000..e07573cf0f
--- /dev/null
+++ b/src/backend/nodes/freefuncs.c
@@ -0,0 +1,1381 @@
+ /*-------------------------------------------------------------------------
+ *
+ * freefuncs.c--
+ *	  Free functions for Postgres tree nodes.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.1 1999/02/06 16:50:25 wieck Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <stdio.h>
+#include <string.h>
+
+#include "postgres.h"
+
+#include "nodes/pg_list.h"
+#include "nodes/execnodes.h"
+#include "nodes/plannodes.h"
+#include "nodes/parsenodes.h"
+#include "nodes/primnodes.h"
+#include "nodes/relation.h"
+
+#include "utils/syscache.h"
+#include "utils/builtins.h"		/* for namecpy */
+#include "utils/elog.h"
+#include "utils/palloc.h"
+#include "catalog/pg_type.h"
+#include "storage/lmgr.h"
+#include "optimizer/planmain.h"
+
+/* ****************************************************************
+ *					 plannodes.h free functions
+ * ****************************************************************
+ */
+
+/* ----------------
+ *		FreePlanFields
+ *
+ *		This function frees the fields of the Plan node.  It is used by
+ *		all the free functions for classes which inherit node Plan.
+ * ----------------
+ */
+static void
+FreePlanFields(Plan *node)
+{
+	freeObject(node->targetlist);
+	freeObject(node->qual);
+	freeObject(node->lefttree);
+	freeObject(node->righttree);
+	freeList(node->extParam);
+	freeList(node->locParam);
+	freeList(node->chgParam);
+	freeObject(node->initPlan);
+	freeList(node->subPlan);
+}
+
+/* ----------------
+ *		_freePlan
+ * ----------------
+ */
+static void
+_freePlan(Plan *node)
+{
+	/* ----------------
+	 *	free the node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields(node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	pfree(node);
+}
+
+
+/* ----------------
+ *		_freeResult
+ * ----------------
+ */
+static void
+_freeResult(Result *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->resconstantqual);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeAppend
+ * ----------------
+ */
+static void
+_freeAppend(Append *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->appendplans);
+	freeObject(node->unionrtables);
+	freeObject(node->inheritrtable);
+
+	pfree(node);
+}
+
+
+/* ----------------
+ *		FreeScanFields
+ *
+ *		This function frees the fields of the Scan node.  It is used by
+ *		all the free functions for classes which inherit node Scan.
+ * ----------------
+ */
+static void
+FreeScanFields(Scan *node)
+{
+}
+
+/* ----------------
+ *		_freeScan
+ * ----------------
+ */
+static void
+_freeScan(Scan *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeScanFields((Scan *) node);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeSeqScan
+ * ----------------
+ */
+static void
+_freeSeqScan(SeqScan *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeScanFields((Scan *) node);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeIndexScan
+ * ----------------
+ */
+static void
+_freeIndexScan(IndexScan *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeScanFields((Scan *) node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeList(node->indxid);
+	freeObject(node->indxqual);
+	freeObject(node->indxqualorig);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		FreeJoinFields
+ *
+ *		This function frees the fields of the Join node.  It is used by
+ *		all the free functions for classes which inherit node Join.
+ * ----------------
+ */
+static void
+FreeJoinFields(Join *node)
+{
+	/* nothing extra */
+	return;
+}
+
+
+/* ----------------
+ *		_freeJoin
+ * ----------------
+ */
+static void
+_freeJoin(Join *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeJoinFields(node);
+
+	pfree(node);
+}
+
+
+/* ----------------
+ *		_freeNestLoop
+ * ----------------
+ */
+static void
+_freeNestLoop(NestLoop *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeJoinFields((Join *) node);
+
+	pfree(node);
+}
+
+
+/* ----------------
+ *		_freeMergeJoin
+ * ----------------
+ */
+static void
+_freeMergeJoin(MergeJoin *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeJoinFields((Join *) node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->mergeclauses);
+
+	pfree(node->mergerightorder);
+	pfree(node->mergeleftorder);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeHashJoin
+ * ----------------
+ */
+static void
+_freeHashJoin(HashJoin *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeJoinFields((Join *) node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->hashclauses);
+
+	pfree(node);
+}
+
+
+/* ----------------
+ *		FreeTempFields
+ *
+ *		This function frees the fields of the Temp node.  It is used by
+ *		all the free functions for classes which inherit node Temp.
+ * ----------------
+ */
+static void
+FreeTempFields(Temp *node)
+{
+	return;
+}
+
+
+/* ----------------
+ *		_freeTemp
+ * ----------------
+ */
+static void
+_freeTemp(Temp *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeTempFields(node);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeMaterial
+ * ----------------
+ */
+static void
+_freeMaterial(Material *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeTempFields((Temp *) node);
+
+	pfree(node);
+}
+
+
+/* ----------------
+ *		_freeSort
+ * ----------------
+ */
+static void
+_freeSort(Sort *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeTempFields((Temp *) node);
+
+	pfree(node);
+}
+
+
+/* ----------------
+ *		_freeGroup
+ * ----------------
+ */
+static void
+_freeGroup(Group *node)
+{
+	FreePlanFields((Plan *) node);
+
+	pfree(node->grpColIdx);
+
+	pfree(node);
+}
+
+/* ---------------
+ *	_freeAgg
+ * --------------
+ */
+static void
+_freeAgg(Agg *node)
+{
+	FreePlanFields((Plan *) node);
+
+	freeList(node->aggs);
+
+	pfree(node);
+}
+
+/* ---------------
+ *	_freeGroupClause
+ * --------------
+ */
+static void
+_freeGroupClause(GroupClause *node)
+{
+	freeObject(node->entry);
+
+	pfree(node);
+}
+
+
+/* ----------------
+ *		_freeUnique
+ * ----------------
+ */
+static void
+_freeUnique(Unique *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+	FreeTempFields((Temp *) node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	if (node->uniqueAttr)
+		pfree(node->uniqueAttr);
+
+	pfree(node);
+}
+
+
+/* ----------------
+ *		_freeHash
+ * ----------------
+ */
+static void
+_freeHash(Hash *node)
+{
+	/* ----------------
+	 *	free node superclass fields
+	 * ----------------
+	 */
+	FreePlanFields((Plan *) node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->hashkey);
+
+	pfree(node);
+}
+
+static void
+_freeSubPlan(SubPlan *node)
+{
+	freeObject(node->plan);
+	freeObject(node->rtable);
+	freeList(node->setParam);
+	freeList(node->parParam);
+	freeObject(node->sublink);
+
+	pfree(node);
+}
+
+/* ****************************************************************
+ *					   primnodes.h free functions
+ * ****************************************************************
+ */
+
+/* ----------------
+ *		_freeResdom
+ * ----------------
+ */
+static void
+_freeResdom(Resdom *node)
+{
+	if (node->resname != NULL)
+		pfree(node->resname);
+
+	pfree(node);
+}
+
+static void
+_freeFjoin(Fjoin *node)
+{
+	freeObject(node->fj_innerNode);
+	pfree(node->fj_results);
+	pfree(node->fj_alwaysDone);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeExpr
+ * ----------------
+ */
+static void
+_freeExpr(Expr *node)
+{
+	freeObject(node->oper);
+	freeObject(node->args);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeVar
+ * ----------------
+ */
+static void
+_freeVar(Var *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	pfree(node);
+}
+
+static void
+_freeFcache(FunctionCachePtr ptr)
+{
+	if (ptr->argOidVect)
+		pfree(ptr->argOidVect);
+	if (ptr->nullVect)
+		pfree(ptr->nullVect);
+	if (ptr->src)
+		pfree(ptr->src);
+	if (ptr->bin)
+		pfree(ptr->bin);
+	if (ptr->func_state)
+		pfree(ptr->func_state);
+	if (ptr->setArg)
+		pfree(ptr->setArg);
+
+	pfree(ptr);
+}
+
+/* ----------------
+ *		_freeOper
+ * ----------------
+ */
+static void
+_freeOper(Oper *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	if (node->op_fcache)
+		_freeFcache(node->op_fcache);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeConst
+ * ----------------
+ */
+static void
+_freeConst(Const *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	if (!node->constbyval)
+		pfree((void *)node->constvalue);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeParam
+ * ----------------
+ */
+static void
+_freeParam(Param *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	if (node->paramname != NULL)
+		pfree(node->paramname);
+	freeObject(node->param_tlist);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeFunc
+ * ----------------
+ */
+static void
+_freeFunc(Func *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->func_tlist);
+	freeObject(node->func_planlist);
+	if (node->func_fcache)
+		_freeFcache(node->func_fcache);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeAggref
+ * ----------------
+ */
+static void
+_freeAggref(Aggref *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	pfree(node->aggname);
+	freeObject(node->target);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeSubLink
+ * ----------------
+ */
+static void
+_freeSubLink(SubLink *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->lefthand);
+	freeObject(node->oper);
+	freeObject(node->subselect);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeCaseExpr
+ * ----------------
+ */
+static void
+_freeCaseExpr(CaseExpr *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->arg);
+	freeObject(node->args);
+	freeObject(node->defresult);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeCaseWhen
+ * ----------------
+ */
+static void
+_freeCaseWhen(CaseWhen *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->expr);
+	freeObject(node->result);
+
+	pfree(node);
+}
+
+static void
+_freeArray(Array *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	pfree(node);
+}
+
+static void
+_freeArrayRef(ArrayRef *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->refupperindexpr);
+	freeObject(node->reflowerindexpr);
+	freeObject(node->refexpr);
+	freeObject(node->refassgnexpr);
+
+	pfree(node);
+}
+
+/* ****************************************************************
+ *						relation.h free functions
+ * ****************************************************************
+ */
+
+/* ----------------
+ *		_freeRelOptInfo
+ * ----------------
+ */
+static void
+_freeRelOptInfo(RelOptInfo * node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeList(node->relids);
+
+	freeObject(node->targetlist);
+	freeObject(node->pathlist);
+	freeObject(node->unorderedpath);
+	freeObject(node->cheapestpath);
+
+	if (node->classlist)
+		pfree(node->classlist);
+
+	if (node->indexkeys)
+		pfree(node->indexkeys);
+
+	freeObject(node->indpred);
+
+	if (node->ordering)
+		pfree(node->ordering);
+
+	freeObject(node->restrictinfo);
+	freeObject(node->joininfo);
+	freeObject(node->innerjoin);
+	freeObject(node->superrels);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		FreePathFields
+ *
+ *		This function frees the fields of the Path node.  It is used by
+ *		all the free functions for classes which inherit node Path.
+ * ----------------
+ */
+static void
+FreePathFields(Path *node)
+{
+	if (node->p_ordering.ordtype == SORTOP_ORDER)
+	{
+		if (node->p_ordering.ord.sortop)
+			pfree(node->p_ordering.ord.sortop);
+	}
+	else
+		freeObject(node->p_ordering.ord.merge);
+
+	freeObject(node->keys);
+
+	freeList(node->joinid);
+	freeObject(node->loc_restrictinfo);
+}
+
+/* ----------------
+ *		_freePath
+ * ----------------
+ */
+static void
+_freePath(Path *node)
+{
+	FreePathFields(node);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeIndexPath
+ * ----------------
+ */
+static void
+_freeIndexPath(IndexPath *node)
+{
+	/* ----------------
+	 *	free the node superclass fields
+	 * ----------------
+	 */
+	FreePathFields((Path *) node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeList(node->indexid);
+	freeObject(node->indexqual);
+
+	if (node->indexkeys)
+		pfree(node->indexkeys);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		FreeJoinPathFields
+ *
+ *		This function frees the fields of the JoinPath node.  It is used by
+ *		all the free functions for classes which inherit node JoinPath.
+ * ----------------
+ */
+static void
+FreeJoinPathFields(JoinPath *node)
+{
+	freeObject(node->pathinfo);
+	freeObject(node->outerjoinpath);
+	freeObject(node->innerjoinpath);
+}
+
+/* ----------------
+ *		_freeJoinPath
+ * ----------------
+ */
+static void
+_freeJoinPath(JoinPath *node)
+{
+	/* ----------------
+	 *	free the node superclass fields
+	 * ----------------
+	 */
+	FreePathFields((Path *) node);
+	FreeJoinPathFields(node);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeMergePath
+ * ----------------
+ */
+static void
+_freeMergePath(MergePath *node)
+{
+	/* ----------------
+	 *	free the node superclass fields
+	 * ----------------
+	 */
+	FreePathFields((Path *) node);
+	FreeJoinPathFields((JoinPath *) node);
+
+	/* ----------------
+	 *	free the remainder of the node
+	 * ----------------
+	 */
+	freeObject(node->path_mergeclauses);
+	freeObject(node->outersortkeys);
+	freeObject(node->innersortkeys);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeHashPath
+ * ----------------
+ */
+static void
+_freeHashPath(HashPath *node)
+{
+	/* ----------------
+	 *	free the node superclass fields
+	 * ----------------
+	 */
+	FreePathFields((Path *) node);
+	FreeJoinPathFields((JoinPath *) node);
+
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->path_hashclauses);
+	freeObject(node->outerhashkeys);
+	freeObject(node->innerhashkeys);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeOrderKey
+ * ----------------
+ */
+static void
+_freeOrderKey(OrderKey *node)
+{
+	pfree(node);
+}
+
+
+/* ----------------
+ *		_freeJoinKey
+ * ----------------
+ */
+static void
+_freeJoinKey(JoinKey *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->outer);
+	freeObject(node->inner);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeMergeOrder
+ * ----------------
+ */
+static void
+_freeMergeOrder(MergeOrder *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeRestrictInfo
+ * ----------------
+ */
+static void
+_freeRestrictInfo(RestrictInfo * node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeObject(node->clause);
+	freeObject(node->indexids);
+	freeObject(node->mergejoinorder);
+	freeList(node->restrictinfojoinid);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		FreeJoinMethodFields
+ *
+ *		This function frees the fields of the JoinMethod node.  It is used by
+ *		all the free functions for classes which inherit node JoinMethod.
+ * ----------------
+ */
+static void
+FreeJoinMethodFields(JoinMethod *node)
+{
+	freeObject(node->jmkeys);
+	freeObject(node->clauses);
+	return;
+}
+
+/* ----------------
+ *		_freeJoinMethod
+ * ----------------
+ */
+static void
+_freeJoinMethod(JoinMethod *node)
+{
+	FreeJoinMethodFields(node);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeHInfo
+ * ----------------
+ */
+static void
+_freeHashInfo(HashInfo *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	FreeJoinMethodFields((JoinMethod *) node);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeMInfo
+ * ----------------
+ */
+static void
+_freeMergeInfo(MergeInfo *node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	FreeJoinMethodFields((JoinMethod *) node);
+	freeObject(node->m_ordering);
+
+	pfree(node);
+}
+
+/* ----------------
+ *		_freeJoinInfo
+ * ----------------
+ */
+static void
+_freeJoinInfo(JoinInfo * node)
+{
+	/* ----------------
+	 *	free remainder of node
+	 * ----------------
+	 */
+	freeList(node->otherrels);
+	freeObject(node->jinfo_restrictinfo);
+
+	pfree(node);
+}
+
+static void
+_freeIter(Iter *node)
+{
+	freeObject(node->iterexpr);
+
+	pfree(node);
+}
+
+static void
+_freeStream(Stream *node)
+{
+	freeObject(node->downstream);
+
+	pfree(node);
+}
+
+/* ****************
+ *			  parsenodes.h routines have no free functions
+ * ****************
+ */
+
+static void
+_freeTargetEntry(TargetEntry *node)
+{
+	freeObject(node->resdom);
+	freeObject(node->fjoin);
+	freeObject(node->expr);
+
+	pfree(node);
+}
+
+static void
+_freeRangeTblEntry(RangeTblEntry *node)
+{
+	if (node->relname)
+		pfree(node->relname);
+	if (node->refname)
+		pfree(node->refname);
+
+	pfree(node);
+}
+
+static void
+_freeRowMark(RowMark *node)
+{
+	pfree(node);
+}
+
+static void
+_freeSortClause(SortClause *node)
+{
+	freeObject(node->resdom);
+
+	pfree(node);
+}
+
+static void
+_freeAConst(A_Const *node)
+{
+	freeObject(&(node->val));
+	freeObject(node->typename);
+
+	pfree(node);
+}
+
+static void
+_freeTypeName(TypeName *node)
+{
+	if (node->name)
+		pfree(node->name);
+	freeObject(node->arrayBounds);
+
+	pfree(node);
+}
+
+static void
+_freeQuery(Query *node)
+{
+	if (node->utilityStmt && nodeTag(node->utilityStmt) == T_NotifyStmt)
+	{
+		NotifyStmt *node_notify = (NotifyStmt *) node->utilityStmt;
+
+		pfree(node_notify->relname);
+		pfree(node_notify);
+	}
+	if (node->into)
+		pfree(node->into);
+	if (node->uniqueFlag)
+		pfree(node->uniqueFlag);
+
+	freeObject(node->sortClause);
+	freeObject(node->rtable);
+	freeObject(node->targetList);
+	freeObject(node->qual);
+	freeObject(node->groupClause);
+	freeObject(node->havingQual);
+	freeObject(node->unionClause);
+	freeObject(node->limitOffset);
+	freeObject(node->limitCount);
+	freeObject(node->rowMark);
+
+	pfree(node);
+}
+
+
+/* ****************
+ *			  mnodes.h routines have no free functions
+ * ****************
+ */
+
+/* ****************************************************************
+ *					pg_list.h free functions
+ * ****************************************************************
+ */
+
+static void
+_freeValue(Value *node)
+{
+	switch (node->type)
+	{
+		case T_String:
+			pfree(node->val.str);
+			break;
+		default:
+			break;
+	}
+
+	pfree(node);
+}
+
+/* ----------------
+ *		freeObject free's the node or list. If it is a list, it
+ *		recursively frees its items.
+ * ----------------
+ */
+void
+freeObject(void *node)
+{
+	if (node == NULL)
+		return;
+
+	switch (nodeTag(node))
+	{
+
+			/*
+			 * PLAN NODES
+			 */
+		case T_Plan:
+			_freePlan(node);
+			break;
+		case T_Result:
+			_freeResult(node);
+			break;
+		case T_Append:
+			_freeAppend(node);
+			break;
+		case T_Scan:
+			_freeScan(node);
+			break;
+		case T_SeqScan:
+			_freeSeqScan(node);
+			break;
+		case T_IndexScan:
+			_freeIndexScan(node);
+			break;
+		case T_Join:
+			_freeJoin(node);
+			break;
+		case T_NestLoop:
+			_freeNestLoop(node);
+			break;
+		case T_MergeJoin:
+			_freeMergeJoin(node);
+			break;
+		case T_HashJoin:
+			_freeHashJoin(node);
+			break;
+		case T_Temp:
+			_freeTemp(node);
+			break;
+		case T_Material:
+			_freeMaterial(node);
+			break;
+		case T_Sort:
+			_freeSort(node);
+			break;
+		case T_Group:
+			_freeGroup(node);
+			break;
+		case T_Agg:
+			_freeAgg(node);
+			break;
+		case T_GroupClause:
+			_freeGroupClause(node);
+			break;
+		case T_Unique:
+			_freeUnique(node);
+			break;
+		case T_Hash:
+			_freeHash(node);
+			break;
+		case T_SubPlan:
+			_freeSubPlan(node);
+			break;
+
+			/*
+			 * PRIMITIVE NODES
+			 */
+		case T_Resdom:
+			_freeResdom(node);
+			break;
+		case T_Fjoin:
+			_freeFjoin(node);
+			break;
+		case T_Expr:
+			_freeExpr(node);
+			break;
+		case T_Var:
+			_freeVar(node);
+			break;
+		case T_Oper:
+			_freeOper(node);
+			break;
+		case T_Const:
+			_freeConst(node);
+			break;
+		case T_Param:
+			_freeParam(node);
+			break;
+		case T_Func:
+			_freeFunc(node);
+			break;
+		case T_Array:
+			_freeArray(node);
+			break;
+		case T_ArrayRef:
+			_freeArrayRef(node);
+			break;
+		case T_Aggref:
+			_freeAggref(node);
+			break;
+		case T_SubLink:
+			_freeSubLink(node);
+			break;
+		case T_CaseExpr:
+			_freeCaseExpr(node);
+			break;
+		case T_CaseWhen:
+			_freeCaseWhen(node);
+			break;
+
+			/*
+			 * RELATION NODES
+			 */
+		case T_RelOptInfo:
+			_freeRelOptInfo(node);
+			break;
+		case T_Path:
+			_freePath(node);
+			break;
+		case T_IndexPath:
+			_freeIndexPath(node);
+			break;
+		case T_JoinPath:
+			_freeJoinPath(node);
+			break;
+		case T_MergePath:
+			_freeMergePath(node);
+			break;
+		case T_HashPath:
+			_freeHashPath(node);
+			break;
+		case T_OrderKey:
+			_freeOrderKey(node);
+			break;
+		case T_JoinKey:
+			_freeJoinKey(node);
+			break;
+		case T_MergeOrder:
+			_freeMergeOrder(node);
+			break;
+		case T_RestrictInfo:
+			_freeRestrictInfo(node);
+			break;
+		case T_JoinMethod:
+			_freeJoinMethod(node);
+			break;
+		case T_HashInfo:
+			_freeHashInfo(node);
+			break;
+		case T_MergeInfo:
+			_freeMergeInfo(node);
+			break;
+		case T_JoinInfo:
+			_freeJoinInfo(node);
+			break;
+		case T_Iter:
+			_freeIter(node);
+			break;
+		case T_Stream:
+			_freeStream(node);
+			break;
+
+			/*
+			 * PARSE NODES
+			 */
+		case T_Query:
+			_freeQuery(node);
+			break;
+		case T_TargetEntry:
+			_freeTargetEntry(node);
+			break;
+		case T_RangeTblEntry:
+			_freeRangeTblEntry(node);
+			break;
+		case T_RowMark:
+			_freeRowMark(node);
+			break;
+		case T_SortClause:
+			_freeSortClause(node);
+			break;
+		case T_A_Const:
+			_freeAConst(node);
+			break;
+		case T_TypeName:
+			_freeTypeName(node);
+			break;
+
+			/*
+			 * VALUE NODES
+			 */
+		case T_Integer:
+		case T_String:
+		case T_Float:
+			_freeValue(node);
+			break;
+		case T_List:
+			{
+				List	   *list = node,
+						   *l;
+
+				foreach(l, list)
+					freeObject(lfirst(l));
+				freeList(list);
+			}
+			break;
+		default:
+			elog(ERROR, "freeObject: don't know how to free %d", nodeTag(node));
+			break;
+	}
+}
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index 008c629e5c..15b5094881 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -7,12 +7,18 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.11 1998/09/01 04:33:34 momjian Exp $
- *
- * NOTE
- *	  XXX This is a preliminary implementation which lacks fail-fast
- *	  XXX validity checking of arguments.
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.12 1999/02/06 16:50:25 wieck Exp $
  *
+ * NOTE:
+ *	This is a new (Feb. 05, 1999) implementation of the allocation set
+ *	routines. AllocSet...() does not use OrderedSet...() any more.
+ *	Instead it manages allocations in a block pool by itself, combining
+ *	many small allocations in a few bigger blocks. AllocSetFree() does
+ *	never free() memory really. It just add's the free'd area to some
+ *	list for later reuse by AllocSetAlloc(). All memory blocks are free()'d
+ *	on AllocSetReset() at once, what happens when the memory context gets
+ *	destroyed.
+ *				Jan Wieck
  *-------------------------------------------------------------------------
  */
 #include <stdio.h>
@@ -25,56 +31,59 @@
 #include <string.h>
 #endif
 
-static void AllocPointerDump(AllocPointer pointer);
-static int AllocSetIterate(AllocSet set,
-				void (*function) (AllocPointer pointer));
 
 #undef AllocSetReset
 #undef malloc
 #undef free
+#undef realloc
+
 
 /*
- * Internal type definitions
+#define	ALLOC_BLOCK_SIZE	8192
+#define	ALLOC_CHUNK_LIMIT	512
+ *
+ * The above settings for block size and chunk limit gain better
+ * performance. But the ones below force a bug that I didn't found
+ * up to now letting the portals_p2 regression test fail.
+ *
  */
+#define	ALLOC_BLOCK_SIZE	16384
+#define	ALLOC_CHUNK_LIMIT	256
 
-/*
- * AllocElem --
- *		Allocation element.
+#define ALLOC_BLOCKHDRSZ	MAXALIGN(sizeof(AllocBlockData))
+#define ALLOC_CHUNKHDRSZ	MAXALIGN(sizeof(AllocChunkData))
+
+#define AllocPointerGetChunk(ptr)	\
+					((AllocChunk)(((char *)(ptr)) - ALLOC_CHUNKHDRSZ))
+#define AllocChunkGetPointer(chk)	\
+					((AllocPointer)(((char *)(chk)) + ALLOC_CHUNKHDRSZ))
+#define AllocPointerGetAset(ptr)	((AllocSet)(AllocPointerGetChunk(ptr)->aset))
+#define AllocPointerGetSize(ptr)	(AllocPointerGetChunk(ptr)->size)
+
+
+
+/* ----------
+ * AllocSetFreeIndex -
+ *
+ *		Depending on the size of an allocation compute which freechunk
+ *		list of the alloc set it belongs to.
+ * ----------
  */
-typedef struct AllocElemData
+static inline int
+AllocSetFreeIndex(Size size)
 {
-	OrderedElemData elemData;	/* elem in AllocSet */
-	Size		size;
-} AllocElemData;
+	int idx = 0;
 
-typedef AllocElemData *AllocElem;
+	size = (size - 1) >> 4;
+	while (size != 0 && idx < 7)
+	{
+		idx++;
+		size >>= 1;
+	}
 
-
-/*
- * Private method definitions
- */
-
-/*
- * AllocPointerGetAllocElem --
- *		Returns allocation (internal) elem given (external) pointer.
- */
-#define AllocPointerGetAllocElem(pointer)		(&((AllocElem)(pointer))[-1])
-
-/*
- * AllocElemGetAllocPointer --
- *		Returns allocation (external) pointer given (internal) elem.
- */
-#define AllocElemGetAllocPointer(alloc) ((AllocPointer)&(alloc)[1])
-
-/*
- * AllocElemIsValid --
- *		True iff alloc is valid.
- */
-#define AllocElemIsValid(alloc) PointerIsValid(alloc)
-
-/* non-export function prototypes */
-static AllocPointer AllocSetGetFirst(AllocSet set);
-static AllocPointer AllocPointerGetNext(AllocPointer pointer);
+	return idx;
+}
+			
 
 /*
  * Public routines
@@ -111,9 +120,10 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit)
 	 * limit is also ignored.  This affects this whole file.
 	 */
 
-	OrderedSetInit(&set->setData, offsetof(AllocElemData, elemData));
+	memset(set, 0, sizeof(AllocSetData));
 }
 
+
 /*
  * AllocSetReset --
  *		Frees memory which is allocated in the given set.
@@ -124,28 +134,21 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit)
 void
 AllocSetReset(AllocSet set)
 {
-	AllocPointer pointer;
+	AllocBlock		block = set->blocks;
+	AllocBlock		next;
 
 	AssertArg(AllocSetIsValid(set));
 
-	while (AllocPointerIsValid(pointer = AllocSetGetFirst(set)))
-		AllocSetFree(set, pointer);
+	while (block != NULL)
+	{
+		next = block->next;
+		free(block);
+		block = next;
+	}
+
+	memset(set, 0, sizeof(AllocSetData));
 }
 
-#ifdef NOT_USED
-void
-AllocSetReset_debug(char *file, int line, AllocSet set)
-{
-	AllocPointer pointer;
-
-	AssertArg(AllocSetIsValid(set));
-
-	while (AllocPointerIsValid(pointer = AllocSetGetFirst(set)))
-		AllocSetFree(set, pointer);
-}
-
-#endif
-
 /*
  * AllocSetContains --
  *		True iff allocation set contains given allocation element.
@@ -160,8 +163,7 @@ AllocSetContains(AllocSet set, AllocPointer pointer)
 	AssertArg(AllocSetIsValid(set));
 	AssertArg(AllocPointerIsValid(pointer));
 
-	return (OrderedSetContains(&set->setData,
-						  &AllocPointerGetAllocElem(pointer)->elemData));
+	return (AllocPointerGetAset(pointer) == set);
 }
 
 /*
@@ -176,23 +178,107 @@ AllocSetContains(AllocSet set, AllocPointer pointer)
 AllocPointer
 AllocSetAlloc(AllocSet set, Size size)
 {
-	AllocElem	alloc;
+	AllocBlock		block;
+	AllocChunk		chunk;
+	AllocChunk		freeref = NULL;
+	int				fidx;
+	Size			chunk_size;
 
 	AssertArg(AllocSetIsValid(set));
 
-	/* allocate */
-	alloc = (AllocElem) malloc(sizeof(*alloc) + size);
+	/*
+	 * Lookup in the corresponding free list if there is a
+	 * free chunk we could reuse
+	 *
+	 */
+	fidx = AllocSetFreeIndex(size);
+	for (chunk = set->freelist[fidx]; chunk; chunk = (AllocChunk)chunk->aset)
+	{
+		if (chunk->size >= size)
+			break;
+		freeref = chunk;
+	}
 
-	if (!PointerIsValid(alloc))
-		elog(FATAL, "palloc failure: memory exhausted");
+	/*
+	 * If found, remove it from the free list, make it again
+	 * a member of the alloc set and return it's data address.
+	 *
+	 */
+	if (chunk != NULL)
+	{
+		if (freeref == NULL)
+			set->freelist[fidx] = (AllocChunk)chunk->aset;
+		else
+			freeref->aset = chunk->aset;
 
-	/* add to allocation list */
-	OrderedElemPushInto(&alloc->elemData, &set->setData);
+		chunk->aset = (void *)set;
+		return AllocChunkGetPointer(chunk);
+	}
 
-	/* set size */
-	alloc->size = size;
+	/*
+	 * If requested size exceeds smallchunk limit, allocate a separate,
+	 * entire used block for this allocation
+	 *
+	 */
+	if (size > ALLOC_CHUNK_LIMIT)
+	{
+		Size	blksize;
 
-	return AllocElemGetAllocPointer(alloc);
+		chunk_size = MAXALIGN(size);
+		blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
+		block = (AllocBlock) malloc(blksize);
+		if (block == NULL)
+			elog(FATAL, "Memory exhausted in AllocSetAlloc()");
+		block->aset = set;
+		block->freeptr = block->endptr = ((char *)block) + ALLOC_BLOCKHDRSZ;
+
+		chunk = (AllocChunk) (((char *)block) + ALLOC_BLOCKHDRSZ);
+		chunk->aset = set;
+		chunk->size = chunk_size;
+
+		if (set->blocks != NULL)
+		{
+			block->next = set->blocks->next;
+			set->blocks->next = block;
+		}
+		else
+		{
+			block->next = NULL;
+			set->blocks = block;
+		}
+
+		return AllocChunkGetPointer(chunk);
+	}
+
+	chunk_size = 16 << fidx;
+
+	if ((block = set->blocks) != NULL)
+	{
+		Size		have_free = block->endptr - block->freeptr;
+
+		if (have_free < (chunk_size + ALLOC_CHUNKHDRSZ))
+			block = NULL;
+	}
+
+	if (block == NULL)
+	{
+		block = (AllocBlock) malloc(ALLOC_BLOCK_SIZE);
+		if (block == NULL)
+			elog(FATAL, "Memory exhausted in AllocSetAlloc()");
+		block->aset = set;
+		block->next = set->blocks;
+		block->freeptr = ((char *)block) + ALLOC_BLOCKHDRSZ;
+		block->endptr = ((char *)block) + ALLOC_BLOCK_SIZE;
+
+		set->blocks = block;
+	}
+
+	chunk = (AllocChunk)(block->freeptr);
+	chunk->aset = (void *)set;
+	chunk->size = chunk_size;
+	block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
+
+	return AllocChunkGetPointer(chunk);
 }
 
 /*
@@ -207,19 +293,18 @@ AllocSetAlloc(AllocSet set, Size size)
 void
 AllocSetFree(AllocSet set, AllocPointer pointer)
 {
-	AllocElem	alloc;
+	int				fidx;
+	AllocChunk		chunk;
 
 	/* AssertArg(AllocSetIsValid(set)); */
 	/* AssertArg(AllocPointerIsValid(pointer)); */
 	AssertArg(AllocSetContains(set, pointer));
 
-	alloc = AllocPointerGetAllocElem(pointer);
+	chunk = AllocPointerGetChunk(pointer);
+	fidx = AllocSetFreeIndex(chunk->size);
 
-	/* remove from allocation set */
-	OrderedElemPop(&alloc->elemData);
-
-	/* free storage */
-	free(alloc);
+	chunk->aset = (void *)set->freelist[fidx];
+	set->freelist[fidx] = chunk;
 }
 
 /*
@@ -238,25 +323,26 @@ AllocPointer
 AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size)
 {
 	AllocPointer newPointer;
-	AllocElem	alloc;
+	Size		oldsize;
 
 	/* AssertArg(AllocSetIsValid(set)); */
 	/* AssertArg(AllocPointerIsValid(pointer)); */
 	AssertArg(AllocSetContains(set, pointer));
 
 	/*
-	 * Calling realloc(3) directly is not be possible (unless we use our
-	 * own hacked version of malloc) since we must keep the allocations in
-	 * the allocation set.
+	 * Chunk sizes are aligned to power of 2 on AllocSetAlloc().
+	 * Maybe the allocated area already is >= the new size.
+	 *
 	 */
-
-	alloc = AllocPointerGetAllocElem(pointer);
+	if (AllocPointerGetSize(pointer) >= size)
+		return pointer;
 
 	/* allocate new pointer */
 	newPointer = AllocSetAlloc(set, size);
 
 	/* fill new memory */
-	memmove(newPointer, pointer, (alloc->size < size) ? alloc->size : size);
+	oldsize = AllocPointerGetSize(pointer);
+	memmove(newPointer, pointer, (oldsize < size) ? oldsize : size);
 
 	/* free old pointer */
 	AllocSetFree(set, pointer);
@@ -264,118 +350,6 @@ AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size)
 	return newPointer;
 }
 
-/*
- * AllocSetIterate --
- *		Returns size of set.  Iterates through set elements calling function
- *		(if valid) on each.
- *
- * Note:
- *		This was written as an aid to debugging.  It is intended for
- *		debugging use only.
- *
- * Exceptions:
- *		BadArg if set is invalid.
- */
-static int
-AllocSetIterate(AllocSet set,
-				void (*function) (AllocPointer pointer))
-{
-	int			count = 0;
-	AllocPointer pointer;
-
-	AssertArg(AllocSetIsValid(set));
-
-	for (pointer = AllocSetGetFirst(set);
-		 AllocPointerIsValid(pointer);
-		 pointer = AllocPointerGetNext(pointer))
-	{
-
-		if (PointerIsValid(function))
-			(*function) (pointer);
-		count += 1;
-	}
-
-	return count;
-}
-
-#ifdef NOT_USED
-int
-AllocSetCount(AllocSet set)
-{
-	int			count = 0;
-	AllocPointer pointer;
-
-	AssertArg(AllocSetIsValid(set));
-
-	for (pointer = AllocSetGetFirst(set);
-		 AllocPointerIsValid(pointer);
-		 pointer = AllocPointerGetNext(pointer))
-		count++;
-	return count;
-}
-
-#endif
-
-/*
- * Private routines
- */
-
-/*
- * AllocSetGetFirst --
- *		Returns "first" allocation pointer in a set.
- *
- * Note:
- *		Assumes set is valid.
- */
-static AllocPointer
-AllocSetGetFirst(AllocSet set)
-{
-	AllocElem	alloc;
-
-	alloc = (AllocElem) OrderedSetGetHead(&set->setData);
-
-	if (!AllocElemIsValid(alloc))
-		return NULL;
-
-	return AllocElemGetAllocPointer(alloc);
-}
-
-/*
- * AllocPointerGetNext --
- *		Returns "successor" allocation pointer.
- *
- * Note:
- *		Assumes pointer is valid.
- */
-static AllocPointer
-AllocPointerGetNext(AllocPointer pointer)
-{
-	AllocElem	alloc;
-
-	alloc = (AllocElem)
-		OrderedElemGetSuccessor(&AllocPointerGetAllocElem(pointer)->elemData);
-
-	if (!AllocElemIsValid(alloc))
-		return NULL;
-
-	return AllocElemGetAllocPointer(alloc);
-}
-
-
-/*
- * Debugging routines
- */
-
-/*
- * XXX AllocPointerDump --
- *		Displays allocated pointer.
- */
-static void
-AllocPointerDump(AllocPointer pointer)
-{
-	printf("\t%-10ld@ %0#lx\n", ((long *) pointer)[-1], (long) pointer);		/* XXX */
-}
-
 /*
  * AllocSetDump --
  *		Displays allocated set.
@@ -383,8 +357,5 @@ AllocPointerDump(AllocPointer pointer)
 void
 AllocSetDump(AllocSet set)
 {
-	int			count;
-
-	count = AllocSetIterate(set, AllocPointerDump);
-	printf("\ttotal %d allocations\n", count);
+	elog(DEBUG, "Currently unable to dump AllocSet");
 }
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 46c3869785..f0e2ee06f7 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.10 1998/09/01 04:33:36 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.11 1999/02/06 16:50:26 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -103,10 +103,11 @@ static struct MemoryContextMethodsData GlobalContextMethodsData = {
  */
 /* extern bool EqualGlobalMemory(); */
 
-static struct GlobalMemory TopGlobalMemoryData = {
+static struct GlobalMemoryData TopGlobalMemoryData = {
 	T_GlobalMemory,				/* NodeTag				tag		  */
 	&GlobalContextMethodsData,	/* ContextMethods		method	  */
-	{{0}},						/* uninitialized OrderedSetData allocSetD */
+	{ NULL, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
+								/* free AllocSet   */
 	"TopGlobal",				/* char* name	   */
 	{0}							/* uninitialized OrderedElemData elemD */
 };
@@ -162,7 +163,7 @@ EnableMemoryContext(bool on)
 
 		/* make TopGlobalMemoryData member of ActiveGlobalMemorySet */
 		OrderedSetInit(ActiveGlobalMemorySet,
-					   offsetof(struct GlobalMemory, elemData));
+					   offsetof(struct GlobalMemoryData, elemData));
 		OrderedElemPushInto(&TopGlobalMemoryData.elemData,
 							ActiveGlobalMemorySet);
 
@@ -371,7 +372,7 @@ CreateGlobalMemory(char *name)	/* XXX MemoryContextName */
 
 	savecxt = MemoryContextSwitchTo(TopMemoryContext);
 
-	context = (GlobalMemory) newNode(sizeof(struct GlobalMemory), T_GlobalMemory);
+	context = (GlobalMemory) newNode(sizeof(struct GlobalMemoryData), T_GlobalMemory);
 	context->method = &GlobalContextMethodsData;
 	context->name = name;		/* assumes name is static */
 	AllocSetInit(&context->setData, DynamicAllocMode, (Size) 0);
diff --git a/src/backend/utils/mmgr/palloc.c b/src/backend/utils/mmgr/palloc.c
index 9c50c3a302..ad4e506f2f 100644
--- a/src/backend/utils/mmgr/palloc.c
+++ b/src/backend/utils/mmgr/palloc.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/palloc.c,v 1.9 1999/01/17 03:04:54 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/palloc.c,v 1.10 1999/02/06 16:50:27 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,98 +22,26 @@
 
 #include "nodes/memnodes.h"
 
-#include "utils/palloc.h"
 
 /* ----------------------------------------------------------------
  *		User library functions
  * ----------------------------------------------------------------
  */
 
-#undef palloc
-#undef pfree
-#undef MemoryContextAlloc
-#undef MemoryContextFree
-#undef malloc
-#undef free
-
-/* define PALLOC_IS_MALLOC if you want palloc to go straight to the
-   raw malloc, without concern for the extra bookkeeping needed to
-   ensure garbage is collected at the end of transactions - jolly 1/12/94 */
-
-
-/*
- * palloc --
- *		Returns pointer to aligned memory of specified size.
- *
- * Exceptions:
- *		BadArgument if size < 1 or size >= MaxAllocSize.
- *		ExhaustedMemory if allocation fails.
- *		NonallocatedPointer if pointer was not returned by palloc or repalloc
- *				or may have been freed already.
- *
- * pfree --
- *		Frees memory associated with pointer returned from palloc or repalloc.
- *
- * Exceptions:
- *		BadArgument if pointer is invalid.
- *		FreeInWrongContext if pointer was allocated in a different "context."
- *		NonallocatedPointer if pointer was not returned by palloc or repalloc
- *				or may have been subsequently freed.
+/* ----------
+ * palloc(), pfree() and repalloc() are now macros in palloc.h
+ * ----------
  */
-void *
-palloc(Size size)
-{
-#ifdef PALLOC_IS_MALLOC
-	return malloc(size);
-#else
-	return MemoryContextAlloc(CurrentMemoryContext, size);
-#endif	 /* PALLOC_IS_MALLOC */
-}
 
-void
-pfree(void *pointer)
-{
-#ifdef PALLOC_IS_MALLOC
-	free(pointer);
-#else
-	MemoryContextFree(CurrentMemoryContext, pointer);
-#endif	 /* PALLOC_IS_MALLOC */
-}
-
-/*
- * repalloc --
- *		Returns pointer to aligned memory of specified size.
- *
- * Side effects:
- *		The returned memory is first filled with the contents of *pointer
- *		up to the minimum of size and psize(pointer).  Pointer is freed.
- *
- * Exceptions:
- *		BadArgument if pointer is invalid or size < 1 or size >= MaxAllocSize.
- *		ExhaustedMemory if allocation fails.
- *		NonallocatedPointer if pointer was not returned by palloc or repalloc
- *				or may have been freed already.
- */
-void *
-repalloc(void *pointer, Size size)
-{
-#ifdef PALLOC_IS_MALLOC
-	return realloc(pointer, size);
-#else
-	return MemoryContextRealloc(CurrentMemoryContext, pointer, size);
-#endif
-}
-
-/* pstrdup
-	allocates space for and copies a string
-	just like strdup except it uses palloc instead of malloc */
 char *
 pstrdup(char *string)
 {
-	char	   *nstr;
+	char		*nstr;
+	int			len;
 
-	nstr = (char *) palloc(strlen(string) + 1);
-	strcpy(nstr, string);
+	nstr = palloc(len = strlen(string) + 1);
+	MemoryCopy(nstr, string, len);
 
 	return nstr;
 }
+
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index c6c31bc181..1aa456b943 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.16 1999/02/03 21:17:40 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.17 1999/02/06 16:50:28 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -812,6 +812,25 @@ PortalDestroy(Portal *portalP)
 					  (Pointer) portal->name);
 	AllocSetReset(&portal->variable.setData);	/* XXX log */
 
+	/*
+	 * In the case of a transaction abort it is possible that
+	 * we get called while one of the memory contexts of the portal
+	 * we're destroying is the current memory context.
+	 * 
+	 * Don't know how to handle that cleanly because it is required
+	 * to be in that context right now. This portal struct remains
+	 * allocated in the PortalMemory context until backend dies.
+	 *
+	 * Not happy with that, but it's better to loose some bytes of
+	 * memory than to have the backend dump core.
+	 *
+	 * --- Feb. 04, 1999 Jan Wieck
+	 */
+	if (CurrentMemoryContext == (MemoryContext)PortalGetHeapMemory(portal))
+		return;
+	if (CurrentMemoryContext == (MemoryContext)PortalGetVariableMemory(portal))
+		return;
+
 	if (portal != BlankPortal)
 		MemoryContextFree((MemoryContext) PortalMemory, (Pointer) portal);
 }
diff --git a/src/include/nodes/memnodes.h b/src/include/nodes/memnodes.h
index accf6ed131..4be4fe4262 100644
--- a/src/include/nodes/memnodes.h
+++ b/src/include/nodes/memnodes.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: memnodes.h,v 1.8 1998/09/01 04:36:39 momjian Exp $
+ * $Id: memnodes.h,v 1.9 1999/02/06 16:50:30 wieck Exp $
  *
  * XXX the typedefs in this file are different from the other ???nodes.h;
  *	  they are pointers to structures instead of the structures themselves.
@@ -56,7 +56,7 @@ typedef struct MemoryContextMethodsData
 	void		(*dump) ();
 }		   *MemoryContextMethods;
 
-typedef struct MemoryContext
+typedef struct MemoryContextData
 {
 	NodeTag		type;
 	MemoryContextMethods method;
@@ -64,7 +64,7 @@ typedef struct MemoryContext
 
 /* think about doing this right some time but we'll have explicit fields
    for now -ay 10/94 */
-typedef struct GlobalMemory
+typedef struct GlobalMemoryData
 {
 	NodeTag		type;
 	MemoryContextMethods method;
@@ -75,14 +75,14 @@ typedef struct GlobalMemory
 
 typedef MemoryContext *PortalMemoryContext;
 
-typedef struct PortalVariableMemory
+typedef struct PortalVariableMemoryData
 {
 	NodeTag		type;
 	MemoryContextMethods method;
 	AllocSetData setData;
 }		   *PortalVariableMemory;
 
-typedef struct PortalHeapMemory
+typedef struct PortalHeapMemoryData
 {
 	NodeTag		type;
 	MemoryContextMethods method;
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index d001c33c99..2635f1d760 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodes.h,v 1.38 1999/02/04 03:19:10 momjian Exp $
+ * $Id: nodes.h,v 1.39 1999/02/06 16:50:31 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -282,6 +282,11 @@ extern void *stringToNode(char *str);
  */
 extern void *copyObject(void *obj);
 
+/*
+ * nodes/freefuncs.c
+ */
+extern void freeObject(void *obj);
+
 /*
  * nodes/equalfuncs.c
  */
diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h
index 9e1adb796f..0bf4f6ef13 100644
--- a/src/include/utils/memutils.h
+++ b/src/include/utils/memutils.h
@@ -15,7 +15,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: memutils.h,v 1.19 1998/12/26 18:15:53 momjian Exp $
+ * $Id: memutils.h,v 1.20 1999/02/06 16:50:33 wieck Exp $
  *
  * NOTES
  *	  some of the information in this file will be moved to
@@ -208,13 +208,41 @@ typedef enum AllocMode
 
 #define DefaultAllocMode		DynamicAllocMode
 
+/*
+ * AllocBlock --
+ *		Small pieces of memory are taken from bigger blocks of
+ *		memory with a size aligned to a power of two. These
+ *		pieces are not free's separately, instead they are reused
+ *		for the next allocation of a fitting size.
+ */
+typedef struct AllocBlockData {
+	struct AllocSetData			*aset;
+	struct AllocBlockData		*next;
+	char						*freeptr;
+	char						*endptr;
+} AllocBlockData;
+
+typedef AllocBlockData *AllocBlock;
+
+/*
+ * AllocChunk --
+ *		The prefix of each piece of memory in an AllocBlock
+ */
+typedef struct AllocChunkData {
+	void						*aset;
+	Size						size;
+} AllocChunkData;
+
+typedef AllocChunkData *AllocChunk;
+
 /*
  * AllocSet --
  *		Allocation set.
  */
 typedef struct AllocSetData
 {
-	OrderedSetData setData;
+	struct AllocBlockData		*blocks;
+	struct AllocChunkData		*freelist[8];
 	/* Note: this will change in the future to support other modes */
 } AllocSetData;
 
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index 2c969df174..05fccc81a3 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -6,18 +6,34 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: palloc.h,v 1.6 1998/09/01 04:39:24 momjian Exp $
+ * $Id: palloc.h,v 1.7 1999/02/06 16:50:34 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
 #ifndef PALLOC_H
 #define PALLOC_H
 
-#include <c.h>
+#include "c.h"
 
-extern void *palloc(Size size);
-extern void pfree(void *pointer);
-extern void *repalloc(void *pointer, Size size);
+#ifdef PALLOC_IS_MALLOC
+
+#  define palloc(s)		malloc(s)
+#  define pfree(p)		free(p)
+#  define repalloc(p,s)	realloc((p),(s))
+
+#else /* ! PALLOC_IS_MALLOC */
+
+/* ----------
+ * In the case we use memory contexts, use macro's for palloc() etc.
+ * ----------
+ */
+#  include "utils/mcxt.h"
+
+#  define palloc(s)		((void *)MemoryContextAlloc(CurrentMemoryContext,(Size)(s)))
+#  define pfree(p)		MemoryContextFree(CurrentMemoryContext,(Pointer)(p))
+#  define repalloc(p,s)	((void *)MemoryContextRealloc(CurrentMemoryContext,(Pointer)(p),(Size)(s)))
+
+#endif /* PALLOC_IS_MALLOC */
 
 /* like strdup except uses palloc */
 extern char *pstrdup(char *pointer);
diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h
index 2c73972121..b718221cb5 100644
--- a/src/include/utils/portal.h
+++ b/src/include/utils/portal.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: portal.h,v 1.10 1998/09/01 04:39:25 momjian Exp $
+ * $Id: portal.h,v 1.11 1999/02/06 16:50:34 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,8 +44,8 @@ typedef PortalD *Portal;
 struct PortalD
 {
 	char	   *name;			/* XXX PortalName */
-	struct PortalVariableMemory variable;
-	struct PortalHeapMemory heap;
+	struct PortalVariableMemoryData variable;
+	struct PortalHeapMemoryData heap;
 	QueryDesc  *queryDesc;
 	TupleDesc	attinfo;
 	EState	   *state;