From 5aeefad98f7929355a231e5782a19402adc583e3 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 22 Jul 2015 15:39:44 +0900 Subject: [PATCH 2/3] Replace use of malloc by an internal memory context in plperl This makes the code more flexible by using the internal memory context infrastructure instead of a system-level memory call. --- src/pl/plperl/plperl.c | 54 ++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 78baaac..327d262 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -108,6 +108,7 @@ typedef struct plperl_proc_desc TransactionId fn_xmin; /* xmin/TID of procedure's pg_proc tuple */ ItemPointerData fn_tid; int refcount; /* reference count of this struct */ + MemoryContext memcxt; /* memory context where this lives */ SV *reference; /* CODE reference for Perl sub */ plperl_interp_desc *interp; /* interpreter it's created in */ bool fn_readonly; /* is function readonly (not volatile)? */ @@ -2588,18 +2589,16 @@ free_plperl_function(plperl_proc_desc *prodesc) SvREFCNT_dec(prodesc->reference); activate_interpreter(oldinterp); } - /* Get rid of what we conveniently can of our own structs */ - /* (FmgrInfo subsidiary info will get leaked ...) */ - if (prodesc->proname) - free(prodesc->proname); - list_free(prodesc->trftypes); - free(prodesc); + + /* Finish destroying this data */ + MemoryContextDelete(prodesc->memcxt); } static plperl_proc_desc * compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger) { + volatile MemoryContext plan_cxt = NULL; HeapTuple procTup; Form_pg_proc procStruct; plperl_proc_key proc_key; @@ -2608,6 +2607,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger) int i; plperl_interp_desc *oldinterp = plperl_active_interp; ErrorContextCallback plperl_error_context; + MemoryContext oldcontext = CurrentMemoryContext; /* We'll need the pg_proc tuple in any case... */ procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fn_oid)); @@ -2662,38 +2662,33 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger) /************************************************************ * Allocate a new procedure description block + * + * struct prodesc and subsidiary data all live in plan_cxt. ************************************************************/ - prodesc = (plperl_proc_desc *) malloc(sizeof(plperl_proc_desc)); - if (prodesc == NULL) - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); - /* Initialize all fields to 0 so free_plperl_function is safe */ - MemSet(prodesc, 0, sizeof(plperl_proc_desc)); - + plan_cxt = AllocSetContextCreate(TopMemoryContext, + "PL/Perl compile", + ALLOCSET_SMALL_MINSIZE, + ALLOCSET_SMALL_INITSIZE, + ALLOCSET_SMALL_MAXSIZE); + MemoryContextSwitchTo(plan_cxt); + prodesc = (plperl_proc_desc *) palloc0(sizeof(plperl_proc_desc)); prodesc->proname = strdup(NameStr(procStruct->proname)); - if (prodesc->proname == NULL) - { - free_plperl_function(prodesc); - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); - } + MemoryContextSwitchTo(oldcontext); + prodesc->memcxt = plan_cxt; prodesc->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data); prodesc->fn_tid = procTup->t_self; + /* Remember if function is STABLE/IMMUTABLE */ prodesc->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE); { - MemoryContext oldcxt; - protrftypes_datum = SysCacheGetAttr(PROCOID, procTup, Anum_pg_proc_protrftypes, &isnull); - oldcxt = MemoryContextSwitchTo(TopMemoryContext); + MemoryContextSwitchTo(plan_cxt); prodesc->trftypes = isnull ? NIL : oid_array_to_list(protrftypes_datum); - MemoryContextSwitchTo(oldcxt); + MemoryContextSwitchTo(oldcontext); } /************************************************************ @@ -2762,7 +2757,9 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger) prodesc->fn_retisarray = (typeStruct->typlen == -1 && typeStruct->typelem); - perm_fmgr_info(typeStruct->typinput, &(prodesc->result_in_func)); + fmgr_info_cxt(typeStruct->typinput, + &(prodesc->result_in_func), + plan_cxt); prodesc->result_typioparam = getTypeIOParam(typeTup); ReleaseSysCache(typeTup); @@ -2804,8 +2801,9 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger) else { prodesc->arg_is_rowtype[i] = false; - perm_fmgr_info(typeStruct->typoutput, - &(prodesc->arg_out_func[i])); + fmgr_info_cxt(typeStruct->typoutput, + &(prodesc->arg_out_func[i]), + plan_cxt); } /* Identify array attributes */ -- 2.4.6