plperl: memory usage stacking

Started by Nonameabout 21 years ago3 messages
#1Noname
biz@html.ne.jp

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);

#2Andrew Dunstan
andrew@dunslane.net
In reply to: Noname (#1)
Re: plperl: memory usage stacking

Please submit as a context diff (made with diff -c) and send it to the
-patches list, rather than -hackers.

cheers

andrew

biz@html.ne.jp wrote:

Show quoted text

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 majordomo@postgresql.org

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#2)
Re: plperl: memory usage stacking

Andrew Dunstan <andrew@dunslane.net> writes:

Please submit as a context diff (made with diff -c) and send it to the
-patches list, rather than -hackers.

It would also help if you'd identify what version the diff is against.
I can't match up any of this with current sources...

regards, tom lane