Subject: | Memory leaks when returning arrays or hashes from JS |
Date: | Fri, 9 Jun 2017 18:51:11 +0100 |
To: | bug-JavaScript-V8 [...] rt.cpan.org |
From: | Elod Csirmaz <elod.news [...] gmail.com> |
Broken in: 0.7.0
The following test script shows that JavaScript::V8 leaks memory when
returning arrays or hashes from JS:
use strict;
use JavaScript::V8;
use Devel::Leak;
my $C = JavaScript::V8::Context->new();
$C->eval("function myf(){ return []; }");
my $handle;
my $count = Devel::Leak::NoteSV($handle);
for( my $i = 0; $i < 1; $i++ ) {
my $r = $C->eval("myf()");
}
Devel::Leak::CheckSV($handle);
After a lot of hacking, removing the two lines below from V8Context.cpp
appears to solve the problem:
SV*
V8Context::array2sv(Handle<Array> array, SvMap& seen) {
AV *av = newAV();
SV *rv = newRV_noinc((SV*)av);
// SvREFCNT_inc(rv); // including this leads to memory leaks
...
SV *
V8Context::object2sv(Handle<Object> obj, SvMap& seen) {
if (enable_blessing && obj->Has(String::New("__perlPackage"))) {
return object2blessed(obj);
}
HV *hv = newHV();
SV *rv = newRV_noinc((SV*)hv);
// SvREFCNT_inc(rv); // including this leads to memory leaks
It's unclear why the code needed to increase the refcounts in these cases.
I see that the code calls sv_2mortal() on the return values later, but I
think the increase is still not needed.
Any advice on whether this is the right fix would be much appreciated.