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;