In plperl.c, there are some memory leaks, fixed in the following diff file.
Becuase Perl_eval_pv doesnot release stack, repitition of calling
'plperl_trigger_build_args' makes stack growing up.

The next simple example exhaust memory:(using perl v5.8.0)
while (1) {
  AV *av = newAV();
  av_undef(av);
}.
I cannot understand the behavior of AV, so, plperl_get_keys, plperl_get_key, and
plperl_get_elem are deleted, and simply implemented by hv_iter* inlined in the
loop.


Tetsuya.



diff plperl.c plperl.c.org

236,237c236
<       SV *rv = NULL;
<       SV *ret = NULL;
---
>       SV *rv;
239d237
<       char *s;
305,309c303
<       ENTER;
<       SAVETMPS;
<       ret = newSVsv (perl_eval_pv(SvPV(rv, PL_na), TRUE));
<       FREETMPS;
<       LEAVE;
---
>       rv = perl_eval_pv(SvPV(rv, PL_na), TRUE);
312d305
<       SvREFCNT_dec(rv);
314c307
<       return ret;
---
>       return rv;
320a314,316
>       char *key;
>       I32 klen;
>       SV *val;
325,326c321
<       hv_iterinit(hv);
<       while (hv_iternext(hv)){
---
>       while (val = hv_iternextsv(hv, (char**)&key, &klen)){
332a328,371
> static
> AV*
> plperl_get_keys(HV* hv)
> {
>       AV *ret;
>       SV **svp;
>       int key_count;
>       SV *val;
>       char *key;
>       I32 klen;
>       key_count = 0;
>       ret = newAV();
>       
>       while (val = hv_iternextsv(hv, (char**)&key, &klen)){
>               av_store(ret, key_count, eval_pv(key, TRUE));
>               key_count++;
>       }
>       
>       return ret;
> }
> 
> static
> char*
> plperl_get_key(AV* keys, int index)
> {
>       SV **svp;
>       int av_len;
>       
>       av_len = av_len(keys)+1;
>       if (index < av_len) svp = av_fetch(keys, index, FALSE); else return 
> NULL;
>       return SvPV(*svp, PL_na);
> }
> 
> static
> char*
> plperl_get_elem(HV* hash, char* key)
> {
>       SV **svp;
>       if (hv_exists_ent(hash, eval_pv(key, TRUE), FALSE))
>               svp = hv_fetch(hash, key, strlen(key), FALSE); else return NULL;
>       
>       return SvPV(*svp, PL_na);
> }
> 
363a403
>       plkeys = plperl_get_keys(hvNew);
382d421
<       hv_iterinit(hvNew);
384a424
>               char       *src;
388,389d427
<               I32 retlen;
<               SV *sv;
391,396c429,430
<               sv = hv_iternextsv(hvNew, &platt, &retlen);
<               if (sv == NULL)
<                       elog(FATAL, "plperl: interpreter is probably 
corrupted");
<               plval = SvPV(sv, PL_na);
<               if (plval == NULL)
<                       elog(FATAL, "plperl: interpreter is probably 
corrupted");
---
> 
>               platt = plperl_get_key(plkeys, j);
403a438,440
>               plval = plperl_get_elem(hvNew, platt);
>               if (plval == NULL)
>                       elog(FATAL, "plperl: interpreter is probably 
> corrupted");
413,428c450,455
<                       Oid ti;
< 
<                       ti = SPI_gettypeid(tupdesc, modattrs[j]);
<                       if ( ( (ti != TEXTOID) && (ti != BPCHAROID) && (ti != 
VARCHAROID) )  && ( (strlen(plval) == 0) || (strcmp(plval, "(null)") == 0) ) )
<                       {
<                               modvalues[j] = (Datum) 0;
<                               modnulls[j] = 'n';
<                       }
<                       else
<                       {
<                               modvalues[j] = FunctionCall3(&finfo,
<                                                                               
        CStringGetDatum(plval),
<                                                                               
        ObjectIdGetDatum(typelem),
<                                                       
Int32GetDatum(tupdesc->attrs[atti]->atttypmod));
<                               modnulls[j] = ' ';
<                       }
---
>                       src = plval;
>                       modvalues[j] = FunctionCall3(&finfo,
>                                                                               
> CStringGetDatum(src),
>                                                                               
> ObjectIdGetDatum(typelem),
>                                               
> Int32GetDatum(tupdesc->attrs[atti]->atttypmod));
>                       modnulls[j] = ' ';
877d903
<       SvREFCNT_dec(svTD);

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]

Reply via email to