Commit ead64f31 authored by Jan Wieck's avatar Jan Wieck

New alloc set code using a memory block pool for small allocations.

Jan
parent 7d2b3874
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -53,6 +53,7 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
{ {
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple tup; HeapTuple tup;
Oid typoid;
static ScanKeyData typeKey[1] = { static ScanKeyData typeKey[1] = {
{0, Anum_pg_type_typname, F_NAMEEQ} {0, Anum_pg_type_typname, F_NAMEEQ}
...@@ -96,10 +97,12 @@ TypeGetWithOpenRelation(Relation pg_type_desc, ...@@ -96,10 +97,12 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
* oid, which is the oid of the type. * oid, which is the oid of the type.
* ---------------- * ----------------
*/ */
heap_endscan(scan);
*defined = (bool) ((Form_pg_type) GETSTRUCT(tup))->typisdefined; *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;
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -1492,7 +1492,7 @@ ExecRelCheck(Relation rel, HeapTuple tuple)
res = ExecQual(qual, econtext); res = ExecQual(qual, econtext);
pfree(qual); freeObject(qual);
if (!res) if (!res)
return check[i].ccname; return check[i].ccname;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Makefile for nodes # Makefile for nodes
# #
# IDENTIFICATION # 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 ...@@ -14,8 +14,8 @@ include ../../Makefile.global
CFLAGS += -I.. CFLAGS += -I..
OBJS = nodeFuncs.o nodes.o list.o \ OBJS = nodeFuncs.o nodes.o list.o \
copyfuncs.o equalfuncs.o makefuncs.o outfuncs.o readfuncs.o \ copyfuncs.o equalfuncs.o freefuncs.o makefuncs.o outfuncs.o \
print.o read.o readfuncs.o print.o read.o
all: SUBSYS.o all: SUBSYS.o
......
/*-------------------------------------------------------------------------
*
* 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;
}
}
...@@ -7,12 +7,18 @@ ...@@ -7,12 +7,18 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.11 1998/09/01 04:33:34 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.12 1999/02/06 16:50:25 wieck Exp $
*
* NOTE
* XXX This is a preliminary implementation which lacks fail-fast
* XXX validity checking of arguments.
* *
* 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> #include <stdio.h>
...@@ -25,56 +31,59 @@ ...@@ -25,56 +31,59 @@
#include <string.h> #include <string.h>
#endif #endif
static void AllocPointerDump(AllocPointer pointer);
static int AllocSetIterate(AllocSet set,
void (*function) (AllocPointer pointer));
#undef AllocSetReset #undef AllocSetReset
#undef malloc #undef malloc
#undef free #undef free
#undef realloc
/*
* Internal type definitions
*/
/* /*
* AllocElem -- #define ALLOC_BLOCK_SIZE 8192
* Allocation element. #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.
*
*/ */
typedef struct AllocElemData #define ALLOC_BLOCK_SIZE 16384
{ #define ALLOC_CHUNK_LIMIT 256
OrderedElemData elemData; /* elem in AllocSet */
Size size;
} AllocElemData;
typedef AllocElemData *AllocElem; #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)
/*
* Private method definitions
*/
/*
* AllocPointerGetAllocElem --
* Returns allocation (internal) elem given (external) pointer.
*/
#define AllocPointerGetAllocElem(pointer) (&((AllocElem)(pointer))[-1])
/* /* ----------
* AllocElemGetAllocPointer -- * AllocSetFreeIndex -
* Returns allocation (external) pointer given (internal) elem. *
* Depending on the size of an allocation compute which freechunk
* list of the alloc set it belongs to.
* ----------
*/ */
#define AllocElemGetAllocPointer(alloc) ((AllocPointer)&(alloc)[1]) static inline int
AllocSetFreeIndex(Size size)
{
int idx = 0;
/* size = (size - 1) >> 4;
* AllocElemIsValid -- while (size != 0 && idx < 7)
* True iff alloc is valid. {
*/ idx++;
#define AllocElemIsValid(alloc) PointerIsValid(alloc) size >>= 1;
}
/* non-export function prototypes */ return idx;
static AllocPointer AllocSetGetFirst(AllocSet set); }
static AllocPointer AllocPointerGetNext(AllocPointer pointer);
/* /*
* Public routines * Public routines
...@@ -111,9 +120,10 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit) ...@@ -111,9 +120,10 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit)
* limit is also ignored. This affects this whole file. * limit is also ignored. This affects this whole file.
*/ */
OrderedSetInit(&set->setData, offsetof(AllocElemData, elemData)); memset(set, 0, sizeof(AllocSetData));
} }
/* /*
* AllocSetReset -- * AllocSetReset --
* Frees memory which is allocated in the given set. * Frees memory which is allocated in the given set.
...@@ -124,28 +134,21 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit) ...@@ -124,28 +134,21 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit)
void void
AllocSetReset(AllocSet set) AllocSetReset(AllocSet set)
{ {
AllocPointer pointer; AllocBlock block = set->blocks;
AllocBlock next;
AssertArg(AllocSetIsValid(set)); AssertArg(AllocSetIsValid(set));
while (AllocPointerIsValid(pointer = AllocSetGetFirst(set))) while (block != NULL)
AllocSetFree(set, pointer); {
} next = block->next;
free(block);
#ifdef NOT_USED block = next;
void }
AllocSetReset_debug(char *file, int line, AllocSet set)
{
AllocPointer pointer;
AssertArg(AllocSetIsValid(set));
while (AllocPointerIsValid(pointer = AllocSetGetFirst(set))) memset(set, 0, sizeof(AllocSetData));
AllocSetFree(set, pointer);
} }
#endif
/* /*
* AllocSetContains -- * AllocSetContains --
* True iff allocation set contains given allocation element. * True iff allocation set contains given allocation element.
...@@ -160,8 +163,7 @@ AllocSetContains(AllocSet set, AllocPointer pointer) ...@@ -160,8 +163,7 @@ AllocSetContains(AllocSet set, AllocPointer pointer)
AssertArg(AllocSetIsValid(set)); AssertArg(AllocSetIsValid(set));
AssertArg(AllocPointerIsValid(pointer)); AssertArg(AllocPointerIsValid(pointer));
return (OrderedSetContains(&set->setData, return (AllocPointerGetAset(pointer) == set);
&AllocPointerGetAllocElem(pointer)->elemData));
} }
/* /*
...@@ -176,23 +178,107 @@ AllocSetContains(AllocSet set, AllocPointer pointer) ...@@ -176,23 +178,107 @@ AllocSetContains(AllocSet set, AllocPointer pointer)
AllocPointer AllocPointer
AllocSetAlloc(AllocSet set, Size size) AllocSetAlloc(AllocSet set, Size size)
{ {
AllocElem alloc; AllocBlock block;
AllocChunk chunk;
AllocChunk freeref = NULL;
int fidx;
Size chunk_size;
AssertArg(AllocSetIsValid(set)); 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 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;
if (!PointerIsValid(alloc)) chunk->aset = (void *)set;
elog(FATAL, "palloc failure: memory exhausted"); return AllocChunkGetPointer(chunk);
}
/* add to allocation list */ /*
OrderedElemPushInto(&alloc->elemData, &set->setData); * If requested size exceeds smallchunk limit, allocate a separate,
* entire used block for this allocation
*
*/
if (size > ALLOC_CHUNK_LIMIT)
{
Size blksize;
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);
}
/* set size */ chunk_size = 16 << fidx;
alloc->size = size;
return AllocElemGetAllocPointer(alloc); 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) ...@@ -207,19 +293,18 @@ AllocSetAlloc(AllocSet set, Size size)
void void
AllocSetFree(AllocSet set, AllocPointer pointer) AllocSetFree(AllocSet set, AllocPointer pointer)
{ {
AllocElem alloc; int fidx;
AllocChunk chunk;
/* AssertArg(AllocSetIsValid(set)); */ /* AssertArg(AllocSetIsValid(set)); */
/* AssertArg(AllocPointerIsValid(pointer)); */ /* AssertArg(AllocPointerIsValid(pointer)); */
AssertArg(AllocSetContains(set, pointer)); AssertArg(AllocSetContains(set, pointer));
alloc = AllocPointerGetAllocElem(pointer); chunk = AllocPointerGetChunk(pointer);
fidx = AllocSetFreeIndex(chunk->size);
/* remove from allocation set */
OrderedElemPop(&alloc->elemData);
/* free storage */ chunk->aset = (void *)set->freelist[fidx];
free(alloc); set->freelist[fidx] = chunk;
} }
/* /*
...@@ -238,25 +323,26 @@ AllocPointer ...@@ -238,25 +323,26 @@ AllocPointer
AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size) AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size)
{ {
AllocPointer newPointer; AllocPointer newPointer;
AllocElem alloc; Size oldsize;
/* AssertArg(AllocSetIsValid(set)); */ /* AssertArg(AllocSetIsValid(set)); */
/* AssertArg(AllocPointerIsValid(pointer)); */ /* AssertArg(AllocPointerIsValid(pointer)); */
AssertArg(AllocSetContains(set, pointer)); AssertArg(AllocSetContains(set, pointer));
/* /*
* Calling realloc(3) directly is not be possible (unless we use our * Chunk sizes are aligned to power of 2 on AllocSetAlloc().
* own hacked version of malloc) since we must keep the allocations in * Maybe the allocated area already is >= the new size.
* the allocation set. *
*/ */
if (AllocPointerGetSize(pointer) >= size)
alloc = AllocPointerGetAllocElem(pointer); return pointer;
/* allocate new pointer */ /* allocate new pointer */
newPointer = AllocSetAlloc(set, size); newPointer = AllocSetAlloc(set, size);
/* fill new memory */ /* 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 */ /* free old pointer */
AllocSetFree(set, pointer); AllocSetFree(set, pointer);
...@@ -264,118 +350,6 @@ AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size) ...@@ -264,118 +350,6 @@ AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size)
return newPointer; 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 -- * AllocSetDump --
* Displays allocated set. * Displays allocated set.
...@@ -383,8 +357,5 @@ AllocPointerDump(AllocPointer pointer) ...@@ -383,8 +357,5 @@ AllocPointerDump(AllocPointer pointer)
void void
AllocSetDump(AllocSet set) AllocSetDump(AllocSet set)
{ {
int count; elog(DEBUG, "Currently unable to dump AllocSet");
count = AllocSetIterate(set, AllocPointerDump);
printf("\ttotal %d allocations\n", count);
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 = { ...@@ -103,10 +103,11 @@ static struct MemoryContextMethodsData GlobalContextMethodsData = {
*/ */
/* extern bool EqualGlobalMemory(); */ /* extern bool EqualGlobalMemory(); */
static struct GlobalMemory TopGlobalMemoryData = { static struct GlobalMemoryData TopGlobalMemoryData = {
T_GlobalMemory, /* NodeTag tag */ T_GlobalMemory, /* NodeTag tag */
&GlobalContextMethodsData, /* ContextMethods method */ &GlobalContextMethodsData, /* ContextMethods method */
{{0}}, /* uninitialized OrderedSetData allocSetD */ { NULL, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
/* free AllocSet */
"TopGlobal", /* char* name */ "TopGlobal", /* char* name */
{0} /* uninitialized OrderedElemData elemD */ {0} /* uninitialized OrderedElemData elemD */
}; };
...@@ -162,7 +163,7 @@ EnableMemoryContext(bool on) ...@@ -162,7 +163,7 @@ EnableMemoryContext(bool on)
/* make TopGlobalMemoryData member of ActiveGlobalMemorySet */ /* make TopGlobalMemoryData member of ActiveGlobalMemorySet */
OrderedSetInit(ActiveGlobalMemorySet, OrderedSetInit(ActiveGlobalMemorySet,
offsetof(struct GlobalMemory, elemData)); offsetof(struct GlobalMemoryData, elemData));
OrderedElemPushInto(&TopGlobalMemoryData.elemData, OrderedElemPushInto(&TopGlobalMemoryData.elemData,
ActiveGlobalMemorySet); ActiveGlobalMemorySet);
...@@ -371,7 +372,7 @@ CreateGlobalMemory(char *name) /* XXX MemoryContextName */ ...@@ -371,7 +372,7 @@ CreateGlobalMemory(char *name) /* XXX MemoryContextName */
savecxt = MemoryContextSwitchTo(TopMemoryContext); savecxt = MemoryContextSwitchTo(TopMemoryContext);
context = (GlobalMemory) newNode(sizeof(struct GlobalMemory), T_GlobalMemory); context = (GlobalMemory) newNode(sizeof(struct GlobalMemoryData), T_GlobalMemory);
context->method = &GlobalContextMethodsData; context->method = &GlobalContextMethodsData;
context->name = name; /* assumes name is static */ context->name = name; /* assumes name is static */
AllocSetInit(&context->setData, DynamicAllocMode, (Size) 0); AllocSetInit(&context->setData, DynamicAllocMode, (Size) 0);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -22,98 +22,26 @@
#include "nodes/memnodes.h" #include "nodes/memnodes.h"
#include "utils/palloc.h"
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* User library functions * User library functions
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
#undef palloc /* ----------
#undef pfree * palloc(), pfree() and repalloc() are now macros in palloc.h
#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.
*/ */
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 * char *
pstrdup(char *string) pstrdup(char *string)
{ {
char *nstr; char *nstr;
int len;
nstr = (char *) palloc(strlen(string) + 1); nstr = palloc(len = strlen(string) + 1);
strcpy(nstr, string); MemoryCopy(nstr, string, len);
return nstr; return nstr;
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -812,6 +812,25 @@ PortalDestroy(Portal *portalP)
(Pointer) portal->name); (Pointer) portal->name);
AllocSetReset(&portal->variable.setData); /* XXX log */ 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) if (portal != BlankPortal)
MemoryContextFree((MemoryContext) PortalMemory, (Pointer) portal); MemoryContextFree((MemoryContext) PortalMemory, (Pointer) portal);
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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; * XXX the typedefs in this file are different from the other ???nodes.h;
* they are pointers to structures instead of the structures themselves. * they are pointers to structures instead of the structures themselves.
...@@ -56,7 +56,7 @@ typedef struct MemoryContextMethodsData ...@@ -56,7 +56,7 @@ typedef struct MemoryContextMethodsData
void (*dump) (); void (*dump) ();
} *MemoryContextMethods; } *MemoryContextMethods;
typedef struct MemoryContext typedef struct MemoryContextData
{ {
NodeTag type; NodeTag type;
MemoryContextMethods method; MemoryContextMethods method;
...@@ -64,7 +64,7 @@ typedef struct MemoryContext ...@@ -64,7 +64,7 @@ typedef struct MemoryContext
/* think about doing this right some time but we'll have explicit fields /* think about doing this right some time but we'll have explicit fields
for now -ay 10/94 */ for now -ay 10/94 */
typedef struct GlobalMemory typedef struct GlobalMemoryData
{ {
NodeTag type; NodeTag type;
MemoryContextMethods method; MemoryContextMethods method;
...@@ -75,14 +75,14 @@ typedef struct GlobalMemory ...@@ -75,14 +75,14 @@ typedef struct GlobalMemory
typedef MemoryContext *PortalMemoryContext; typedef MemoryContext *PortalMemoryContext;
typedef struct PortalVariableMemory typedef struct PortalVariableMemoryData
{ {
NodeTag type; NodeTag type;
MemoryContextMethods method; MemoryContextMethods method;
AllocSetData setData; AllocSetData setData;
} *PortalVariableMemory; } *PortalVariableMemory;
typedef struct PortalHeapMemory typedef struct PortalHeapMemoryData
{ {
NodeTag type; NodeTag type;
MemoryContextMethods method; MemoryContextMethods method;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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); ...@@ -282,6 +282,11 @@ extern void *stringToNode(char *str);
*/ */
extern void *copyObject(void *obj); extern void *copyObject(void *obj);
/*
* nodes/freefuncs.c
*/
extern void freeObject(void *obj);
/* /*
* nodes/equalfuncs.c * nodes/equalfuncs.c
*/ */
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* some of the information in this file will be moved to * some of the information in this file will be moved to
...@@ -208,13 +208,41 @@ typedef enum AllocMode ...@@ -208,13 +208,41 @@ typedef enum AllocMode
#define DefaultAllocMode DynamicAllocMode #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 -- * AllocSet --
* Allocation set. * Allocation set.
*/ */
typedef struct AllocSetData typedef struct AllocSetData
{ {
OrderedSetData setData; struct AllocBlockData *blocks;
struct AllocChunkData *freelist[8];
/* Note: this will change in the future to support other modes */ /* Note: this will change in the future to support other modes */
} AllocSetData; } AllocSetData;
......
...@@ -6,18 +6,34 @@ ...@@ -6,18 +6,34 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 #ifndef PALLOC_H
#define PALLOC_H #define PALLOC_H
#include <c.h> #include "c.h"
extern void *palloc(Size size); #ifdef PALLOC_IS_MALLOC
extern void pfree(void *pointer);
extern void *repalloc(void *pointer, Size size); # 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 */ /* like strdup except uses palloc */
extern char *pstrdup(char *pointer); extern char *pstrdup(char *pointer);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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; ...@@ -44,8 +44,8 @@ typedef PortalD *Portal;
struct PortalD struct PortalD
{ {
char *name; /* XXX PortalName */ char *name; /* XXX PortalName */
struct PortalVariableMemory variable; struct PortalVariableMemoryData variable;
struct PortalHeapMemory heap; struct PortalHeapMemoryData heap;
QueryDesc *queryDesc; QueryDesc *queryDesc;
TupleDesc attinfo; TupleDesc attinfo;
EState *state; EState *state;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment